/*
  This file is part of KOrganizer.

  Copyright (c) 2001
  Cornelius Schumacher <schumacher@kde.org>

  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.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include <qwidgetstack.h>

#include <kconfig.h>
#include <kglobal.h>
#ifndef DESKTOP_VERSION
#include <qpe/qpeapplication.h>
#else
#include <qapplication.h>
#endif
#include "calendarview.h"
#include "datenavigator.h"
#include "kotodoview.h"
#include "koagendaview.h"
#include "kodialogmanager.h"
#include "komonthview.h"
#include "kolistview.h"
#include "kowhatsnextview.h"
#include "kojournalview.h"
#include "kotimespanview.h"
#include "koprefs.h"
#include "navigatorbar.h"

#include "koviewmanager.h"
//extern bool externFlagMonthviewBlockPainting;

//bool globalFlagBlockPainting = false;
int globalFlagBlockAgenda = 0;
int globalFlagBlockLabel = 0;
int globalFlagBlockAgendaItemPaint = 1;
int globalFlagBlockAgendaItemUpdate = 1;


KOViewManager::KOViewManager( CalendarView *mainView ) :
    QObject(), mMainView( mainView )
{
    mCurrentView = 0;

    mWhatsNextView = 0;
    mTodoView = 0;
    mAgendaView = 0;
    mMonthView = 0;
    mListView = 0;
    mJournalView = 0;
    mTimeSpanView = 0; 
    mCurrentAgendaView = 0 ;
    mFlagShowNextxDays = false;
}

KOViewManager::~KOViewManager()
{
}


KOrg::BaseView *KOViewManager::currentView()
{
    return mCurrentView;
}

void KOViewManager::readSettings(KConfig *config)
{
    config->setGroup("General");
    QString view = config->readEntry("Current View");
    if (view == "WhatsNext") showWhatsNextView();
    else if (view == "Month") showMonthView();
    else if (view == "List") showListView();
    else if (view == "Journal") showJournalView();
    else if (view == "TimeSpan") showTimeSpanView();
    else if (view == "Todo") showTodoView();
    else {
        showAgendaView();
    }
}

void KOViewManager::writeSettings(KConfig *config)
{
    config->setGroup("General");

    QString view;
    if (mCurrentView == mWhatsNextView) view = "WhatsNext";
    else if (mCurrentView == mMonthView) view = "Month";
    else if (mCurrentView == mListView) view = "List";
    else if (mCurrentView == mJournalView) view = "Journal";
    else if (mCurrentView == mTimeSpanView) view = "TimeSpan";
    else if (mCurrentView == mTodoView) view = "Todo";
    else view = "Agenda";

    config->writeEntry("Current View",view);

    if (mAgendaView) {
        mAgendaView->writeSettings(config);
    }
    if (mTimeSpanView) {
        mTimeSpanView->writeSettings(config);
    }
    if (mListView) {
        mListView->writeSettings(config);
    }
    if (mTodoView) {
        mTodoView->saveLayout(config,"Todo View");
    }
}

void KOViewManager::showView(KOrg::BaseView *view, bool fullScreen )
{
 
    //mFlagShowNextxDays = false;
    //if(view == mCurrentView) return;  
    if ( view == 0 ) {
        view = mCurrentView;
        if ( view == 0 )
            return;
    }
    bool full = fullScreen;
    if(view == mCurrentView && view != mWhatsNextView ) {
        if ( mCurrentAgendaView < 0 )
            return;
        full = mMainView->leftFrame()->isVisible();
    } else {
        mCurrentView = view;
        
        // bool full = fullScreen;
        bool isFull = !mMainView->leftFrame()->isVisible();
        if ( isFull && KOPrefs::instance()->mViewChangeHoldFullscreen )
            full = true;
        if ( !isFull && KOPrefs::instance()->mViewChangeHoldNonFullscreen )
            full = false;
    }
    if ( mAgendaView ) mAgendaView->deleteSelectedDateTime();
    raiseCurrentView( full );
    mMainView->processIncidenceSelection( 0 );
    mMainView->updateView();
    mMainView->adaptNavigationUnits();
}

void KOViewManager::raiseCurrentView( bool fullScreen )
{
    //qDebug("raiseCurrentView ");
    mCurrentAgendaView = 0;
    int wid =  mMainView->width() ;
    int hei  = mMainView->height();
    if ( mCurrentView == mMonthView   ) {
        mMainView->navigatorBar()->show();
        hei -= mMainView->navigatorBar()->sizeHint().height();
        //mMainView->navigatorBar()->hide();
    } else {
        mMainView->navigatorBar()->hide();
    }
    if ( fullScreen ) {
        mMainView->leftFrame()->hide();
    } else {
        mMainView->leftFrame()->show();
        if ( KOPrefs::instance()->mVerticalScreen )  
            hei -= mMainView->leftFrame()->height();
        else
            wid -= mMainView->leftFrame()->width();
    }
   
    if ( globalFlagBlockAgenda ==  5 ) {
        globalFlagBlockAgenda =  4;
        globalFlagBlockAgendaItemPaint = 1;
    }
    mMainView->viewStack()->raiseWidget(mCurrentView);
    if ( globalFlagBlockAgenda ==  4 ) {
        if ( mCurrentView == mAgendaView ) {
            //globalFlagBlockAgenda =1 ;
            if ( KOPrefs::instance()->mSetTimeToDayStartAt )
                mAgendaView->setStartHour( KOPrefs::instance()->mDayBegins  );
            else if ( KOPrefs::instance()->mCenterOnCurrentTime )
                mAgendaView->setStartHour( QTime::currentTime ().hour() );
            qApp->processEvents();  
            //qDebug("qApp->processEvents() ");
            globalFlagBlockAgenda = 0;
            mAgendaView->repaintAgenda();

        }
        globalFlagBlockAgenda = 0;
    }
    //qDebug("raiseCurrentView ende ");
}

void KOViewManager::updateView()
{
    // qDebug("KOViewManager::updateView() ");
    // if we are updating mTodoView, we get endless recursion
    if ( mTodoView == mCurrentView )
        return;
    if ( mCurrentView ) mCurrentView->updateView();

}

void KOViewManager::updateView(const QDate &start, const QDate &end)
{
    //  kdDebug() << "KOViewManager::updateView()" << endl;

    if (mCurrentView) mCurrentView->showDates(start, end);

    if (mTodoView) mTodoView->updateView();
}


void KOViewManager::showWhatsNextView()
{
    if (!mWhatsNextView) {
        mWhatsNextView = new KOWhatsNextView(mMainView->calendar(),mMainView->viewStack(),
                                             "KOViewManager::WhatsNextView");
        mWhatsNextView->setEventViewer( mMainView->getEventViewerDialog());
        connect(mMainView, SIGNAL(configChanged()), mWhatsNextView, SLOT(updateConfig()));
        addView(mWhatsNextView);
    }
    globalFlagBlockAgenda = 1;
    showView(mWhatsNextView, true );
    mWhatsNextView->updateView();
 
}

void KOViewManager::showListView()
{
    if (!mListView) {
        mListView = new KOListView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::ListView");
        addView(mListView);

        connect(mListView, SIGNAL(showIncidenceSignal(Incidence *)),
                mMainView, SLOT(showIncidence(Incidence *)));
        connect(mListView, SIGNAL(editIncidenceSignal(Incidence *)),
                mMainView, SLOT(editIncidence(Incidence *)));
        connect(mListView, SIGNAL(deleteIncidenceSignal(Incidence *)),
                mMainView, SLOT(deleteIncidence(Incidence *)));
        connect( mListView, SIGNAL( incidenceSelected( Incidence * ) ),
                 mMainView, SLOT( processMainViewSelection( Incidence * ) ) ); 
        connect( mListView, SIGNAL( signalNewEvent() ),
                 mMainView, SLOT( newEvent() ) );
        connect(mMainView, SIGNAL(configChanged()), mListView, SLOT(updateConfig())); 
        connect( mListView, SIGNAL( cloneIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( cloneIncidence( Incidence * ) ) ); 
        connect( mListView, SIGNAL( cancelIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( cancelIncidence( Incidence * ) ) ); 
        connect( mListView, SIGNAL( moveIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( moveIncidence( Incidence * ) ) );
        connect( mListView, SIGNAL( beamIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( beamIncidence( Incidence * ) ) );
    }
    // bool temp = mFlagShowNextxDays;
    //globalFlagBlockPainting = true;
    globalFlagBlockAgenda = 1;
    if ( KOPrefs::instance()->mListViewMonthTimespan )
        mMainView->dateNavigator()->selectMonth();
    showView(mListView, KOPrefs::instance()->mFullViewTodo);
    //mFlagShowNextxDays = temp;
}

void KOViewManager::showAgendaView( bool fullScreen )
{

    mMainView->dialogManager()->hideSearchDialog();
    // qDebug("KOViewManager::showAgendaView ");
    bool full;
    full = fullScreen;
    if (!mAgendaView) {
        full = false; 
        mAgendaView = new KOAgendaView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::AgendaView"); 
        addView(mAgendaView);
#ifndef DESKTOP_VERSION
        QPEApplication::setStylusOperation( mAgendaView, QPEApplication::RightOnHold );
#endif
        connect( mAgendaView, SIGNAL( incidenceChanged(Incidence  *, int )),
                 mMainView, SLOT( changeIncidenceDisplay( Incidence  *, int ) ));

        // SIGNALS/SLOTS FOR DAY/WEEK VIEW
        connect(mAgendaView,SIGNAL(newEventSignal(QDateTime)),
                mMainView, SLOT(newEvent(QDateTime)));
        // connect(mAgendaView,SIGNAL(newEventSignal(QDateTime,QDateTime)),
        //      mMainView, SLOT(newEvent(QDateTime,QDateTime)));
        connect(mAgendaView,SIGNAL(newEventSignal(QDate)),
                mMainView, SLOT(newEvent(QDate)));

        connect(mAgendaView, SIGNAL(editIncidenceSignal(Incidence *)),
                mMainView, SLOT(editIncidence(Incidence *)));
        connect(mAgendaView, SIGNAL(showIncidenceSignal(Incidence *)),
                mMainView, SLOT(showIncidence(Incidence *)));
        connect(mAgendaView, SIGNAL(deleteIncidenceSignal(Incidence *)),
                mMainView, SLOT(deleteIncidence(Incidence *)));

        connect( mAgendaView, SIGNAL( incidenceSelected( Incidence * ) ),
                 mMainView, SLOT( processMainViewSelection( Incidence * ) ) );

        connect(mAgendaView, SIGNAL( toggleExpand() ),
                mMainView, SLOT( toggleExpand() ) );
       
        connect(mMainView, SIGNAL( calendarViewExpanded( bool ) ),
                mAgendaView, SLOT( setExpandedButton( bool ) ) );
        connect( mAgendaView, SIGNAL( cloneIncidenceSignal(Incidence *) ), 
                 mMainView, SLOT(cloneIncidence(Incidence *) ) ) ;
        connect( mAgendaView, SIGNAL( cancelIncidenceSignal(Incidence *) ), 
                 mMainView, SLOT(cancelIncidence(Incidence *) ) ) ;
        connect(mMainView, SIGNAL(configChanged()), mAgendaView, SLOT(updateConfig())); 
        connect( mMainView, SIGNAL( todoModified( Todo *, int )), mAgendaView,
                 SLOT( updateTodo( Todo *, int ) ) );  
        connect(  mAgendaView,SIGNAL( todoMoved( Todo *, int )),
                  mMainView, SIGNAL( todoModified( Todo *, int )));
        connect( mAgendaView, SIGNAL( moveIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( moveIncidence( Incidence * ) ) );
        connect( mAgendaView, SIGNAL( beamIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( beamIncidence( Incidence * ) ) );
        mAgendaView->readSettings(); 
        mAgendaView->updateConfig(); 
    }
   
    showView( mAgendaView, full);
  
}

void KOViewManager::showDayView()
{
    mFlagShowNextxDays =  false;
    globalFlagBlockLabel = 1;
    globalFlagBlockAgenda = 1;
    if ( mCurrentAgendaView != 1 )
        mCurrentAgendaView = -1;
    showAgendaView();
    qApp->processEvents();  
    globalFlagBlockAgenda = 2;
    globalFlagBlockLabel = 0;
    mMainView->dateNavigator()->selectDates( 1 );
    mCurrentAgendaView = 1 ;
    
}

void KOViewManager::showWorkWeekView()
{
    mFlagShowNextxDays =  false;
    globalFlagBlockAgenda = 1;
    globalFlagBlockLabel = 1;
    if ( mCurrentAgendaView != 5 )
        mCurrentAgendaView = -1;
    showAgendaView();
    qApp->processEvents();  
    globalFlagBlockAgenda = 2;
    globalFlagBlockLabel = 0;
    mMainView->dateNavigator()->selectWorkWeek();
    mCurrentAgendaView = 5 ;
   
}

void KOViewManager::showWeekView()
{
    /*
      globalFlagBlockAgenda = 2;
      qDebug("4globalFlagBlockAgenda = 2; ");
      //globalFlagBlockPainting = true;
      mMainView->dateNavigator()->selectWeek();
      showAgendaView();
    */


    mFlagShowNextxDays = false;
    globalFlagBlockAgenda = 1;
    globalFlagBlockLabel = 1;
    if ( mCurrentAgendaView != 7 )
        mCurrentAgendaView = -1;
    showAgendaView();
    qApp->processEvents();  
    globalFlagBlockAgenda = 2;
    globalFlagBlockLabel = 0;  
    mMainView->dateNavigator()->selectWeek();
    mCurrentAgendaView = 7 ;
}

void KOViewManager::showNextXView()
{
      
    globalFlagBlockAgenda = 1;
    if ( mCurrentAgendaView != 3 )
        mCurrentAgendaView = -1;
    showAgendaView(KOPrefs::instance()->mFullViewMonth);
    globalFlagBlockAgenda = 2;
    mMainView->dateNavigator()->selectDates( QDate::currentDate(),
                                             KOPrefs::instance()->mNextXDays );
    mFlagShowNextxDays = true;
    mCurrentAgendaView = 3 ;
}
bool KOViewManager::showsNextDays() 
{
    return mFlagShowNextxDays;
}
void KOViewManager::showMonthView()
{
    if (!mMonthView) {
        mMonthView = new KOMonthView(mMainView->calendar(), mMainView->viewStack(), "KOViewManager::MonthView");
     
        addView(mMonthView);
        // mMonthView->show();
        // SIGNALS/SLOTS FOR MONTH VIEW
        connect(mMonthView, SIGNAL(newEventSignal(QDateTime)),
                mMainView, SLOT(newEvent(QDateTime)));

        connect(mMonthView, SIGNAL(showIncidenceSignal(Incidence *)),
                mMainView, SLOT(showIncidence(Incidence *)));
        connect(mMonthView, SIGNAL(editIncidenceSignal(Incidence *)),
                mMainView, SLOT(editIncidence(Incidence *)));
        connect(mMonthView, SIGNAL(deleteIncidenceSignal(Incidence *)),
                mMainView, SLOT(deleteIncidence(Incidence *)));

        connect( mMonthView, SIGNAL( incidenceSelected( Incidence * ) ),
                 mMainView, SLOT( processMainViewSelection( Incidence * ) ) );
        connect( mMonthView, SIGNAL( cloneIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( cloneIncidence( Incidence * ) ) );
        connect( mMonthView, SIGNAL( cancelIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( cancelIncidence( Incidence * ) ) );

        connect( mMonthView, SIGNAL( moveIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( moveIncidence( Incidence * ) ) );
        connect( mMonthView, SIGNAL( beamIncidenceSignal( Incidence *  ) ),
                 mMainView, SLOT ( beamIncidence( Incidence * ) ) );
        connect( mMonthView, SIGNAL( selectWeekNum( int ) ),
                 mMainView, SLOT ( selectWeekNum( int ) ) );
        connect(mMainView, SIGNAL(configChanged()), mMonthView, SLOT(updateConfig()));
        mMonthView->updateConfig();
    }

    globalFlagBlockAgenda = 1;
    //mFlagShowNextxDays = false;
    // if(mMonthView == mCurrentView) return;
    mMainView->dateNavigator()->selectMonth();
    // DateList tmpList = mMainView->dateNavigator()->selectedDates( );
    //mMonthView->showDates(tmpList.first(), tmpList.last());

    showView(mMonthView, true );
   
}

void KOViewManager::showTodoView()
{
    //mFlagShowNextxDays = false;
    if ( !mTodoView ) {
        mTodoView = new KOTodoView( mMainView->calendar(), mMainView->viewStack(),
                                    "KOViewManager::TodoView" );
    
        addView( mTodoView ); 
        // QPEApplication::setStylusOperation( mTodoView, QPEApplication::RightOnHold );
  
        // SIGNALS/SLOTS FOR TODO VIEW
        connect( mTodoView, SIGNAL( newTodoSignal() ),
                 mMainView, SLOT( newTodo() ) );
        connect( mTodoView, SIGNAL( newSubTodoSignal( Todo * ) ),
                 mMainView, SLOT( newSubTodo( Todo *) ) );
        connect( mTodoView, SIGNAL( showTodoSignal( Todo *) ),
                 mMainView, SLOT( showTodo( Todo * ) ) );
        connect( mTodoView, SIGNAL( editTodoSignal( Todo * ) ),
                 mMainView, SLOT( editTodo( Todo * ) ) );
        connect( mTodoView, SIGNAL( deleteTodoSignal( Todo * ) ),
                 mMainView, SLOT( deleteTodo( Todo * ) ) );
        connect( mTodoView, SIGNAL( purgeCompletedSignal() ),
                 mMainView, SLOT( purgeCompleted() ) );

        connect( mTodoView, SIGNAL( incidenceSelected( Incidence * ) ),
                 mMainView, SLOT( processMainViewSelection( Incidence * ) ) );

        connect( mMainView, SIGNAL( configChanged() ), mTodoView,
                 SLOT( updateConfig() ) ); 
        connect( mMainView, SIGNAL( todoModified( Todo *, int )), mTodoView,
                 SLOT( updateTodo( Todo *, int ) ) );
        connect( mTodoView, SIGNAL( todoModifiedSignal( Todo *, int ) ),
                 mMainView, SIGNAL ( todoModified( Todo *, int ) ) );
        connect( mTodoView, SIGNAL( cloneTodoSignal( Incidence *  ) ),
                 mMainView, SLOT ( cloneIncidence( Incidence * ) ) );
        connect( mTodoView, SIGNAL( cancelTodoSignal( Incidence *  ) ),
                 mMainView, SLOT ( cancelIncidence( Incidence * ) ) );
        connect( mTodoView, SIGNAL( unparentTodoSignal( Todo * ) ),
                 mMainView, SLOT ( todo_unsub( Todo * ) ) );
        connect( mTodoView, SIGNAL( moveTodoSignal( Incidence *  ) ),
                 mMainView, SLOT ( moveIncidence( Incidence * ) ) );
        connect( mTodoView, SIGNAL( beamTodoSignal( Incidence *  ) ),
                 mMainView, SLOT ( beamIncidence( Incidence * ) ) );
        KConfig *config = KOGlobals::config();
        mTodoView->restoreLayout(config,"Todo View");
    }

    globalFlagBlockAgenda = 1;
    showView( mTodoView, true );

}

void KOViewManager::showJournalView()
{
    //mFlagShowNextxDays = false;
    if (!mJournalView) {
        mJournalView = new KOJournalView(mMainView->calendar(),mMainView->viewStack(),
                                         "KOViewManager::JournalView"); 
        connect( mMainView, SIGNAL( configChanged() ), mJournalView,
                 SLOT( updateConfig() ) );
        connect(mJournalView, SIGNAL(deleteJournal(Journal *) ), mMainView,SLOT(deleteJournal(Journal *)) );
        addView(mJournalView);
    }

    showView(mJournalView);
}

void KOViewManager::showTimeSpanView()
{
    //mFlagShowNextxDays = false;
    if (!mTimeSpanView) {
        mTimeSpanView = new KOTimeSpanView(mMainView->calendar(),mMainView->viewStack(),
                                           "KOViewManager::TimeSpanView");
        addView(mTimeSpanView);

        mTimeSpanView->readSettings();
    }

    showView(mTimeSpanView);
}

Incidence *KOViewManager::currentSelection()
{
    if (!mCurrentView) return 0;
    if ( mCurrentView == mListView ) {
        if ( mListView->currentItem() )
            return mListView->currentItem();
    }
    return mCurrentView->selectedIncidences().first();
}

QDate KOViewManager::currentSelectionDate()
{
    QDate qd;
    if (mCurrentView) {
        DateList qvl = mCurrentView->selectedDates();
        if (!qvl.isEmpty()) qd = qvl.first();
    }
    return qd;
}

void KOViewManager::addView(KOrg::BaseView *view)
{
#if QT_VERSION >= 300
    mMainView->viewStack()->addWidget( view );
#else
    mMainView->viewStack()->addWidget( view, 1 );
#endif
}

void KOViewManager::setDocumentId( const QString &id )
{
    if (mTodoView) mTodoView->setDocumentId( id );
}