/***************************************************************************
 *   Copyright (C) 2004 by Tasuku Suzuki                                   *
 *   tasuku@linux-life.net                                                 *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#define MMPERPIXEL 2.6

#include <qapplication.h>
#include <qfile.h>
#include <qlabel.h>
#include <qlayout.h>

#include <kactionclasses.h>
#include <kapplication.h>
#include <kmainwindow.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kconfig.h>
#include <kaction.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kurl.h>
#include <kfiledialog.h>
#include <kcursor.h>
#include <ksplashscreen.h>
#include <kstandarddirs.h>
#include <kxmlguifactory.h>
#include <kpopupmenu.h>

#include "dlgfilenew.h"
#include "dlgpreferences.h"
#include "kreetingkard.h"
#include "kkview.h"
#include "kkdoc.h"
#include "kkproperty.h"
#include "zipcode.h"

#include "kkaddressbook/kkaddressbookdialog.h"
#include "kkaddressbook/kkprintdialog.h"

KreetingKard::KreetingKard()
    : KDockMainWindow( 0, "KreetingKard" )
{
	m_filename = QString::null;
	setXMLFile("kreetingkardui.rc");
	setupWidgets();
	setupActions();
	createGUI();
	readConfig();
}

KreetingKard::~KreetingKard()
{
	saveConfig();
}

void KreetingKard::setupActions()
{
	KStdAction::openNew( this, SLOT( fileNew() ), actionCollection() );
	KStdAction::open( this, SLOT( fileOpen() ), actionCollection() );
	KStdAction::openRecent( this, SLOT( openRecent( const KURL& ) ), actionCollection() );
	KStdAction::save( this, SLOT( fileSave() ), actionCollection() );
	KStdAction::saveAs( this, SLOT( fileSaveAs() ), actionCollection() );
	KStdAction::print( this, SLOT( print() ), actionCollection() );
	KStdAction::close( this, SLOT( fileClose() ), actionCollection() );
	KStdAction::quit( this, SLOT( close() ), actionCollection() );

	new KAction( i18n( "Insert Item" ), "frame_edit", KShortcut(Qt::Key_Insert), m_view, SLOT( insert() ), actionCollection(), "insert" );

	new KAction( i18n( "Delete Item" ), "eraser", KShortcut(Qt::Key_Delete), m_doc, SLOT( remove() ), actionCollection(), "remove" );

	new KAction( i18n( "Raise" ), "top", 0, m_doc, SLOT( raiseItem() ), actionCollection(), "raise" );

	new KAction( i18n( "Lower" ), "bottom", 0, m_doc, SLOT( lowerItem() ), actionCollection(), "lower" );

	new KAction( i18n( "Address Book" ), "contents", KShortcut(CTRL+Qt::Key_B), this, SLOT( address() ), actionCollection(), "address" );

	KStdAction::selectAll( m_doc, SLOT( selectAll() ), actionCollection() );
	KStdAction::cut( m_doc, SLOT( cut() ), actionCollection() );
	KStdAction::copy( m_doc, SLOT( copy() ), actionCollection() );
	KStdAction::paste( m_doc, SLOT( paste() ), actionCollection() );

	KStdAction::zoomIn( m_view, SLOT( zoomIn() ), actionCollection() );
	KStdAction::zoomOut( m_view, SLOT( zoomOut() ), actionCollection() );

	KStdAction::preferences( this, SLOT( preferences() ), actionCollection() );
	setEnabledEditAction( false );
}

void KreetingKard::readConfig()
{
	KConfig *conf = KGlobal::config();
	conf->setGroup("KreetingKard");
	if( conf->hasKey( "Split" ) )
	{
		m_spl->setSizes( conf->readIntListEntry( "Split" ) );
	}

	QString filename = conf->readEntry( "file", "" );
	if( !filename.isEmpty() )
		fileOpen( filename );

	QString directory = conf->readEntry( "directory", "" );
	if( !directory.isEmpty() )
		m_directory = directory;

	((KRecentFilesAction*)actionCollection()->action( "file_open_recent" ))->loadEntries( conf );
	readDockConfig( conf );
}

void KreetingKard::saveConfig()
{
	KConfig *conf = KGlobal::config();
	conf->setGroup("KreetingKard");
	conf->writeEntry( "Split", m_spl->sizes() );
	conf->writeEntry( "file", m_filename );
	conf->writeEntry( "directory", m_directory );
	((KRecentFilesAction*)actionCollection()->action( "file_open_recent" ))->saveEntries( conf );
	writeDockConfig( conf );
}

void KreetingKard::setupWidgets()
{
	KDockWidget* base = createDockWidget( "list", SmallIcon( "list" ), 0, i18n( "List" ) );
	m_view = new KKView( base );
	connect( m_view, SIGNAL( popup( const QPoint&, bool ) ), this, SLOT( popup( const QPoint&, bool ) ) );
	base->setWidget( m_view );
	base->setDockSite( KDockWidget::DockCorner );
	base->setEnableDocking( KDockWidget::DockNone );
	setView( base );
	setMainDockWidget( base );

	KDockWidget* folder = createDockWidget( "folder", SmallIcon( "folder" ), 0, i18n( "Folder" ), i18n( "Folder" ) );
	m_spl = new QSplitter( Vertical, this );
	m_spl->setOpaqueResize( true );
	m_doc = new KKDoc( actionCollection(), m_spl );
	m_property = new KKProperty( m_spl );
	folder->setWidget( m_spl );
// 	folder->setDockSite( KDockWidget::DockRight );
	// todo config
	folder->manualDock( base, KDockWidget::DockRight, 20 );

	m_view->setDocument( m_doc );
	m_property->setDocument( m_doc );
}

void KreetingKard::fileNew()
{
	if( !checkChangedAndSaved() ) return;
	dlgFileNew dlg( this );
	dlg.exec();
	if( !dlg.result() ) return;

	QFile file( dlg.filename() );
	if( !file.open( IO_ReadOnly ) )
	{
		KMessageBox::error( this, i18n( "File open error" ) );
		return;
	}

	QDomDocument doc( "kreetingkard" );
	if( !doc.setContent( &file ) )
	{
		KMessageBox::error( this, i18n( "File is not kreetingkard format" ) );
		return;
	}
	file.close();

	setEnabledEditAction( true );

	m_doc->setDocument( doc );
	m_view->setFocus();

	m_filename = "";
	setCaption( "" );
}

void KreetingKard::fileOpen()
{
	if( !checkChangedAndSaved() ) return;
	KURL url = KFileDialog::getOpenURL( m_directory, i18n( "*.kk|KreetingKard File (*.kk)" ) );
	if( url.isEmpty() ) return;

	if( !url.isLocalFile() )
	{
		KMessageBox::sorry( this, i18n( "KreetingKard cannot handle remote files yet") );
		return;
	}

	((KRecentFilesAction*)actionCollection()->action( "file_open_recent" ))->addURL( url );
	m_directory = url.directory();
	fileOpen( url.path() );
}

void KreetingKard::fileOpen( const QString &filename, bool checkModified )
{
	if( checkModified )
	{
		if( !checkChangedAndSaved() ) return;
	}
	m_filename = filename;
	QFile file( m_filename );
	if( !file.open( IO_ReadOnly ) )
	{
		KMessageBox::error( this, i18n( "File open error" ) );
		return;
	}

	QDomDocument doc( "kreetingkard" );
	if( !doc.setContent( &file ) )
	{
		KMessageBox::error( this, i18n( "File is not kreetingkard format" ) );
		return;
	}
	file.close();

	setEnabledEditAction( true );

	m_doc->setDocument( doc );

	QFileInfo info( m_filename );
	setCaption( info.baseName() );
}

void KreetingKard::openRecent( const KURL& url )
{
	if( !checkChangedAndSaved() ) return;
	fileOpen( url.path() );
}

bool KreetingKard::fileSave()
{
	if( m_filename.isEmpty() )
	{
		return fileSaveAs();
	}
	QFile file( m_filename );
	if( !file.open( IO_WriteOnly ) )
	{
		KMessageBox::error( this, i18n( "File open error" ) );
		return false;
	}
	QTextStream str( &file );
	str << m_doc->document();
	file.close();
	m_doc->commandHistory()->clear();

	QFileInfo info( m_filename );
	setCaption( info.baseName() );

	actionCollection()->action( "file_save" )->setEnabled( true );
	return true;
}

bool KreetingKard::fileSaveAs()
{
	KURL url = KFileDialog::getSaveURL( m_directory, i18n( "*.kk|KreetingKard File (*.kk)" ), this );
	if( url.isEmpty() ) return false;
	if( !url.isLocalFile() )
	{
		KMessageBox::sorry( this, i18n( "KreetingKard cannot handle remote files yet") );
		return false;
	}
	m_filename = url.path();
	((KRecentFilesAction*)actionCollection()->action( "file_open_recent" ))->addURL( url );
	m_directory = url.directory();
	return fileSave();
}

void KreetingKard::fileClose()
{
	if( !checkChangedAndSaved() ) return;
	m_doc->clearDocument();

	setCaption( "" );
	setEnabledEditAction( false );

	m_filename = QString::null;
}

bool KreetingKard::checkChangedAndSaved()
{
	bool blRtn = true;
	if( actionCollection()->action( "edit_undo" )->isEnabled() )
	{
		int ans = KMessageBox::questionYesNoCancel( this, i18n("This document is modified.\nDo you save change?"), i18n("Confirm") );
		switch( ans )
		{
			case KMessageBox::Yes:
				blRtn = fileSave();
				if( blRtn )
				{
					m_doc->commandHistory()->clear();
				}
				break;
			case KMessageBox::No:
				break;
			case KMessageBox::Cancel:
				blRtn = false;
				break;
		}
	}
	return blRtn;
}

void KreetingKard::setEnabledEditAction( bool bl )
{
	actionCollection()->action( "file_save" )->setEnabled( bl );
	actionCollection()->action( "file_save_as" )->setEnabled( bl );
	actionCollection()->action( "file_print" )->setEnabled( bl );
	actionCollection()->action( "file_close" )->setEnabled( bl );
	actionCollection()->action( "insert" )->setEnabled( bl );
	actionCollection()->action( "remove" )->setEnabled( bl );
	actionCollection()->action( "edit_select_all" )->setEnabled( bl );

	actionCollection()->action( "raise" )->setEnabled( false );
	actionCollection()->action( "lower" )->setEnabled( false );
	actionCollection()->action( "edit_cut" )->setEnabled( false );
	actionCollection()->action( "edit_copy" )->setEnabled( false );
	actionCollection()->action( "edit_paste" )->setEnabled( false );
	actionCollection()->action( "view_zoom_in" )->setEnabled( false );
	actionCollection()->action( "view_zoom_out" )->setEnabled( false );
}

bool KreetingKard::queryClose()
{
	return checkChangedAndSaved();
}

void KreetingKard::address()
{
	KKAddressBookDialog dlg( locateLocal( "data", KGlobal::instance()->instanceName() + "/kkaddress.xml" ), this );
	dlg.exec();
}

void KreetingKard::preferences()
{
	dlgPreferences dlg( this );
	dlg.exec();
}

void KreetingKard::print()
{
	KKPrintDialog dlg( m_doc, locateLocal( "data", KGlobal::instance()->instanceName() + "/kkaddress.xml" ), this );
	dlg.exec();
}

void KreetingKard::popup( const QPoint& pos, bool base )
{
	if( base ){
		( (KPopupMenu*)( factory()->container( "base_popup", this ) ) )->exec( pos );
	}else{
		( (KPopupMenu*)( factory()->container( "item_popup", this ) ) )->exec( pos );
	}
}
