/***************************************************************************
 *   Copyright (C) 2004-2009 by Thomas Fischer                             *
 *   fischer@unix-ag.uni-kl.de                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef KBIBTEXMERGEELEMENTS_H
#define KBIBTEXMERGEELEMENTS_H

#include <kdialogbase.h>

#include <findduplicates.h>
#include <file.h>
#include <entry.h>

class KPushButton;
class KTextEdit;
class KListView;
class QProgressBar;

namespace KBibTeX
{
    class MergeElementsCliqueItem : public QObject, public QCheckListItem
    {
        Q_OBJECT
    public:
        MergeElementsCliqueItem( BibTeX::Entry* entry, BibTeX::Macro* macro, BibTeX::Preamble* preamble, QListView *parent );
        BibTeX::Entry* entry;
        BibTeX::Macro* macro;
        BibTeX::Preamble* preamble;

    protected:
        void stateChange( bool );

    signals:
        void stateChanged( MergeElementsCliqueItem* );
    };

    class MergeEntriesAlternativesController: public QCheckListItem
    {
    public:
        MergeEntriesAlternativesController( const QString &label, QListView *parent );
        MergeEntriesAlternativesController( BibTeX::EntryField::FieldType fieldType, QListView *parent );
        BibTeX::EntryField::FieldType fieldType;
        const QString fieldName;
    };

    class MergeMacrosAlternativesController: public QCheckListItem
    {
    public:
        MergeMacrosAlternativesController( bool isKey, QListView *parent );
    };


    class MergeEntriesAlternativesItem: public QCheckListItem
    {
    public:
        MergeEntriesAlternativesItem( BibTeX::EntryField *field, MergeEntriesAlternativesController *parent );
        BibTeX::EntryField *field;
    };

    class MergeMacrosAlternativesItem: public QCheckListItem
    {
    public:
        MergeMacrosAlternativesItem( BibTeX::Value *value, MergeMacrosAlternativesController *parent );
        BibTeX::Value *value;
    };

    class MergeElementsAlternativesId: public QCheckListItem
    {
    public:
        MergeElementsAlternativesId( const QString &id, MergeEntriesAlternativesController *parent );
        QString id;
    };

    class MergeMacroAlternativesKey: public QCheckListItem
    {
    public:
        MergeMacroAlternativesKey( const QString &key, MergeMacrosAlternativesController *parent );
        QString key;
    };


    class MergeEntriesAlternativesEntryType: public QCheckListItem
    {
    public:
        MergeEntriesAlternativesEntryType( const QString &typeString, MergeEntriesAlternativesController *parent );
        MergeEntriesAlternativesEntryType( BibTeX::Entry::EntryType type, MergeEntriesAlternativesController *parent );
        QString typeString;
        BibTeX::Entry::EntryType type;
    };

    class MergePreambleAlternativesController: public QCheckListItem
    {
    public:
        MergePreambleAlternativesController( QListView *parent );
    };

    class MergePreambleAlternatives: public QCheckListItem
    {
    public:
        MergePreambleAlternatives( const QString &text, MergePreambleAlternativesController *parent );
        QString text;
    };

    /**
     @author Thomas Fischer <fischer@unix-ag.uni-kl.de>
    */
    class MergeElements : public KDialogBase
    {
        Q_OBJECT
    public:
        MergeElements( QWidget *parent );
        ~MergeElements();
        int mergeDuplicates( BibTeX::File *bibTeXFile );

    protected:
        void showEvent( QShowEvent * );

    protected slots:
        void slotRefreshAlternatives();
        void slotNextClique();
        void slotPreviousClique();
        void slotPreviewElement( QListViewItem *item );
        void saveCurrentMergeSet();
        void slotRestore();

    private:
        typedef struct
        {
            BibTeX::Macro *macro;
            BibTeX::Entry *entry;
            BibTeX::EntryField *field;
        } First;

        typedef struct
        {
            QValueList<BibTeX::Macro*> macros;
            QValueList<BibTeX::Entry*> entries;
            QValueList<BibTeX::EntryField*> fields;
            QValueList<BibTeX::Preamble*> preambles;
            QString macroKey;
            BibTeX::Value *macroValue;
            QString id, typeString;
            BibTeX::Entry::EntryType type;
            QString preambleText;
        } MergeSet;

        KListView *m_listViewClique;
        KListView *m_listViewAlternatives;
        QProgressBar *m_progressBar;
        FindDuplicates::DuplicateCliqueList m_duplicateCliqueList;
        MergeSet **m_mergeSetList;
        int m_currentCliqueIndex;

        void setupGUI();
        void setClique( int cliqueIndex );
        void restoreCurrentMergeSet();
        void applyMergeSet( BibTeX::File *bibTeXFile, BibTeX::File *otherBibTeXFile = NULL );
        void restoreWindowSize( KConfig *config );
        void saveWindowSize( KConfig *config ) const;
    };

}

#endif // KBIBTEXMERGEELEMENTS_H
