/***************************************************************************
                          kgeoConstructor.cpp  -  description
                             -------------------
    begin                : Sun Oct 8 2000
    copyright            : (C) 2000 by Marc Bartsch
    email                : marc.bartsch@topmail.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.                                   *
 *                                                                         *
 ***************************************************************************/
//#include <kwin.h>

#include "kgeo.h"

KGeoApp::KGeoApp()
{
	startSplashScreen();

	//	Setup metrics object. The static metrics object contains method
  //  to calculate all sort of geometrical stuff.
	kapp->config()->setGroup( "Grid" );
	MetricsCenter::xMax = 					kapp->config()->readNumEntry( "HighestXValue", 11 );
	MetricsCenter::yMax = 					kapp->config()->readNumEntry( "HighestYValue", 7 );
	MetricsCenter::xRes = 					kapp->desktop()->width();
	MetricsCenter::yRes = 					kapp->desktop()->height();
	MetricsCenter::xDistanceRatio = kapp->config()->readNumEntry( "DistanceRatio", 5 );
	MetricsCenter::isPrinter = false;
	MetricsCenter::grid = 					kapp->config()->readBoolEntry( "GridLines", true );
	MetricsCenter::numbers = 				kapp->config()->readBoolEntry( "Numbers", true );
	MetricsCenter::axes = 					kapp->config()->readBoolEntry( "Axes", true );
	MetricsCenter::generateMetrics();

	// Get configuration object
  config = kapp->config();

	unsavedChanges = false;
	unnamedDrawing = true;

	//	Set Drawing mode to move Objects
	drawingMode = ID_drawingModeMovingObjects;

	//	Whether mouse is over object.
	isOverObject = false;

	//	Set the standard cursor for different modes.
  standardCursor = arrowCursor;

	//	List of all object for faster access.
	objectList.clear();

	//	Init current that object leads to the selected Object.
  currentObject = 0;

	//	Init new object to be drawn.
  newObject = 0;

	//	Create about window
//	aboutWin = new AboutWindow( 0, 0, true, 0 );

	currentButtonID = 0;
	lastButtonID = 0;

	//	Create preferences window
	preferencesDialog = new PreferencesDialog( 0, 0, true, 0 );
	connect( preferencesDialog->buttonApply, SIGNAL( clicked() ), SLOT( savePreferences() ) );

	//	Create kiosk window
 	kiosk = new QDialog( 0, 0, false, WStyle_Customize | WStyle_NoBorder);
	kiosk->setGeometry( 0, 0, kapp->desktop()->width(), kapp->desktop()->height() );

  // call inits to invoke all other construction parts
  initMenuBar();
  initToolBar();
  initStatusBar();

	mainWidget = new MainWidget( this );

	canvas = new GeoWidget ( mainWidget->GeoContainer );
	canvas->setAcceptDrops( true );
	kapp->config()->setGroup( "Grid" );
	canvas->showGridLines( kapp->config()->readBoolEntry( "GridLines", true ) );
	canvas->showNumbers( kapp->config()->readBoolEntry( "Numbers", true ) );
	canvas->showAxes( kapp->config()->readBoolEntry( "Axes", true ) );
	canvas->setNumberRange( kapp->config()->readNumEntry( "HighestXValue", 11 ), kapp->config()->readNumEntry( "HighestYValue", 7 ) );
	canvas->setUnit( kapp->config()->readNumEntry( "DistanceRatio", 5 ) );

 	kapp->config()->setGroup( "Colors" );

	if ( kapp->config()->hasKey( "Background" ) )
	{
		canvas->setBackgroundColor( kapp->config()->readColorEntry( "Background" ) );
	}
	canvas->drawGrid();

  GeoWidgetLayout = new QHBoxLayout( mainWidget->GeoContainer );
  GeoWidgetLayout->setSpacing( 0 );
  GeoWidgetLayout->setMargin( 2 );
  GeoWidgetLayout->addWidget( canvas );

	setCentralWidget( mainWidget );

	//	So far there is only one context menu. Will be extended in future.
	kontextMenu = new QPopupMenu();
	kontextMenu->insertItem(SmallIcon("window_nofullscreen"),  i18n( "E&xit fullscreen mode" ), this, SLOT( endKioskMode() ) );
	
	//	Init currentFilename
	currentFilename = i18n( "No drawing" );
	printFilenameInWindowTitle();

	//	Connect those signal and slots that are necessary for the move mode.
	startMoveMode();
}

KGeoApp::~KGeoApp()
{
}

void KGeoApp::initMenuBar()
{
  ///////////////////////////////////////////////////////////////////
  // MENUBAR
  recentFilesMenu = new QPopupMenu();
  connect(recentFilesMenu, SIGNAL(aboutToShow()), SLOT(fillRecentMenu()));
  connect(recentFilesMenu, SIGNAL(activated(int)), SLOT(loadRecent(int)));
 	kapp->config()->setGroup("Recent");
	kapp->config()->readListEntry( "List", recentFiles );

  ///////////////////////////////////////////////////////////////////
  // menuBar entry fileMenu
  fileMenu = new QPopupMenu();
  fileMenu->insertItem(SmallIcon("filenew"), i18n("&New"), ID_FILE_NEW);
  fileMenu->insertItem(SmallIcon("fileopen"), i18n("&Open..."), ID_FILE_OPEN);
  fileMenu->insertItem(i18n("Open &Recent"), recentFilesMenu, ID_FILE_OPEN_RECENT);

  fileMenu->insertItem(i18n("&Close"), ID_FILE_CLOSE);
  fileMenu->insertSeparator();
  fileMenu->insertItem(SmallIcon("filesave") ,i18n("&Save"), ID_FILE_SAVE);
  fileMenu->insertItem(i18n("Save &As..."), ID_FILE_SAVE_AS);
  fileMenu->insertSeparator();
  fileMenu->insertItem(SmallIcon("fileprint"), i18n("&Print..."), ID_FILE_PRINT);
  fileMenu->insertSeparator();
  fileMenu->insertItem(i18n("&Quit"), ID_FILE_QUIT);

	fileMenu->setAccel( CTRL + Key_N, ID_FILE_NEW );
	fileMenu->setAccel( CTRL + Key_O, ID_FILE_OPEN );
	fileMenu->setAccel( CTRL + Key_C, ID_FILE_CLOSE );
	fileMenu->setAccel( CTRL + Key_S, ID_FILE_SAVE );
	fileMenu->setAccel( CTRL + Key_P, ID_FILE_PRINT );
	fileMenu->setAccel( CTRL + Key_Q, ID_FILE_QUIT );

  ///////////////////////////////////////////////////////////////////
  // menuBar entry editMenu
  editMenu = new QPopupMenu();
  editMenu->insertItem(SmallIcon("configure"), i18n("P&references"), ID_EDIT_PREFERENCES);
  editMenu->insertSeparator();
  editMenu->insertItem(SmallIcon("window_fullscreen"), i18n("&Fullscreen"), ID_EDIT_FULLSCREEN);

	editMenu->setAccel( CTRL + Key_R, ID_EDIT_PREFERENCES );

  ///////////////////////////////////////////////////////////////////
  // menuBar entry helpMenu
   kgeoHelpMenu = new KHelpMenu(this, KGlobal::instance()->aboutData(), false);

  ///////////////////////////////////////////////////////////////////
  // MENUBAR CONFIGURATION
  // insert your popup menus with the according menubar entries in the order
  // they will appear later from left to right
  menuBar()->insertItem(i18n("&File"), fileMenu);
  menuBar()->insertItem(i18n("&Edit"), editMenu);
  menuBar()->insertItem(i18n("&Help"), kgeoHelpMenu->menu());

  connect( fileMenu, SIGNAL( activated( int ) ), SLOT( commandCallback( int ) ) );
  connect( editMenu, SIGNAL( activated( int ) ), SLOT( commandCallback( int ) ) );
}

void KGeoApp::initToolBar()
{
  ///////////////////////////////////////////////////////////////////
  // TOOLBAR
  toolBar()->insertButton( UserIcon("filenew"), ID_FILE_NEW, true, i18n("New File"));
  toolBar()->insertButton( UserIcon("fileopen"), ID_FILE_OPEN, true, i18n("Open File"));
  toolBar()->insertButton( UserIcon("filesave"), ID_FILE_SAVE, true, i18n("Save File"));
  toolBar()->insertButton( UserIcon("fileprint"), ID_FILE_PRINT, true, i18n("Print"));
  toolBar()->insertSeparator();
  toolBar()->insertLineSeparator();
  toolBar()->insertSeparator();
  toolBar()->insertButton( UserIcon("window_fullscreen"), ID_EDIT_FULLSCREEN, true, i18n("Fullscreen"));
  toolBar()->insertSeparator();
  toolBar()->insertLineSeparator();
  toolBar()->insertSeparator();
  toolBar()->insertButton( UserIcon("help"), ID_HELP_CONTENTS, SIGNAL(clicked()),
  				this, SLOT(appHelpActivated()), true,i18n("Help"));
  toolBar()->insertButton( UserIcon("exit"), ID_FILE_QUIT, SIGNAL(clicked()),
  				this, SLOT(slotFileQuit()), true,i18n("Quit"));
	toolBar()->setFullSize( false );
  connect(toolBar(), SIGNAL(clicked(int)), SLOT(commandCallback(int)));

	KToolBar *sizes = new KToolBar( this, QMainWindow::Top, false );
  QComboBox *ptSizeCombo = new QComboBox( sizes );
  ptSizeCombo->setFixedHeight( 26 );
	ptSizeCombo->insertItem( UserIcon( "point1" ) );
	ptSizeCombo->insertItem( UserIcon( "point2" ) );
	ptSizeCombo->insertItem( UserIcon( "point3" ) );
	ptSizeCombo->insertItem( UserIcon( "point4" ) );
	ptSizeCombo->insertItem( UserIcon( "point5" ) );
	ptSizeCombo->insertItem( UserIcon( "point6" ) );
	ptSizeCombo->insertItem( UserIcon( "point7" ) );
	ptSizeCombo->insertItem( UserIcon( "point8" ) );
	ptSizeCombo->insertItem( UserIcon( "point9" ) );
	ptSizeCombo->insertItem( UserIcon( "point10" ) );
	ptSizeCombo->insertItem( UserIcon( "point11" ) );
	ptSizeCombo->insertItem( UserIcon( "point12" ) );
	ptSizeCombo->insertItem( UserIcon( "point13" ) );
	ptSizeCombo->insertItem( UserIcon( "point14" ) );
  QToolTip::add( ptSizeCombo, i18n( "Choose point size" ) );

  kapp->config()->setGroup( "Sizes" );
	ptSizeCombo->setCurrentItem( ( kapp->config()->readNumEntry( "PointSize", MinimumPointSize ) - MinimumPointSize ) );
  connect( ptSizeCombo, SIGNAL( highlighted( int ) ), this, SLOT( setPointSize( int ) ) );

  QComboBox *lineSizeCombo = new QComboBox( sizes );
  lineSizeCombo->setFixedHeight( 26 );
	lineSizeCombo->insertItem( UserIcon( "line1" ) );
	lineSizeCombo->insertItem( UserIcon( "line2" ) );
	lineSizeCombo->insertItem( UserIcon( "line3" ) );
	lineSizeCombo->insertItem( UserIcon( "line4" ) );
	lineSizeCombo->insertItem( UserIcon( "line5" ) );
  QToolTip::add( lineSizeCombo, i18n( "Choose line width" ) );

  kapp->config()->setGroup( "Sizes" );
	lineSizeCombo->setCurrentItem( ( kapp->config()->readNumEntry( "LineWidth", 1 ) - 1 ) );
  connect( lineSizeCombo, SIGNAL( highlighted( int ) ), this, SLOT( setLineWidth( int ) ) );

	sizes->insertWidget( 1000, 0, ptSizeCombo );
	sizes->insertSeparator();
	sizes->insertWidget( 1001, 0, lineSizeCombo );
	sizes->setFullSize( false );

	KToolBar *point = new KToolBar( this, QMainWindow::Left, false );
	point->insertButton( UserIcon("point"), ID_buttonPoint, true, i18n( "Draw a point" ) );
	point->insertButton( UserIcon("pointxy"), ID_buttonPointxy, true, i18n( "Draw a point at (x;y)" ) );
	point->insertButton( UserIcon("pointOnLine"), ID_buttonPointOnLine, true, i18n( "Draw  a point on a line or circle" )  );
	point->insertButton( UserIcon("pointOfConc"), ID_buttonPointOfConc, true,    i18n( "Draw the point of concurrency of two lines or two segments" )  );
	point->insertButton( UserIcon("bisection"), ID_buttonBisection, true,   i18n( "Draw the bisection of two points" )  );
	point->insertButton( UserIcon("mirrorPoint"), ID_buttonMirrorPoint, true,   i18n( "Draw mirror point of point/point or point/line" )  );
	point->insertButton( UserIcon("rotation"), ID_buttonRotation, true,   i18n( "Rotate one point around another using a certain arc" )  );
	point->insertButton( UserIcon("move"), ID_buttonMove, true,   i18n( "Move a point using a vector" )  );
	point->setFullSize( false );

	KToolBar *line = new KToolBar( this, QMainWindow::Left, false );
	line->insertButton( UserIcon("segment"), ID_buttonSegment, true,   i18n( "Draw a segment between two points" )  );
	line->insertButton( UserIcon("line"), ID_buttonLine, true,   i18n( "Draw a line" )  );
	line->insertButton( UserIcon("triangle"), ID_buttonTriangle, true,   i18n( "Draw a triangle" )  );
	line->insertButton( UserIcon("vector"), ID_buttonVector, true,   i18n( "Draw a vector" )  );
	line->insertButton( UserIcon("ray"), ID_buttonRay, true,   i18n( "Draw a ray" )  );
	line->insertButton( UserIcon("parallel"), ID_buttonParallel, true,   i18n( "Draw a parallel of a line" )  );
	line->insertButton( UserIcon("perpendicular"), ID_buttonPerpendicular, true,   i18n( "Draw the perpendicular line of a line through a point" )  );
	line->setFullSize( false );

	KToolBar *circle = new KToolBar( this, QMainWindow::Left, true );
	circle->insertButton( UserIcon("circle"), ID_buttonCircle, true,   i18n( "Draw a circle" )  );
	circle->insertButton( UserIcon("baseCircle"), ID_buttonBaseCircle, true,   i18n( "Draw a circle with a fixed diameter" )  );
	circle->insertButton( UserIcon("arc"), ID_buttonArc, true,   i18n( "Draw an arc" )  );
	circle->setFullSize( false );

	KToolBar *measure = new KToolBar( this, QMainWindow::Left, false );
	measure->insertButton( UserIcon("distance"), ID_buttonDistance, true,   i18n( "Measure the distance between two points" )  );
	measure->insertButton( UserIcon("areaCircle"), ID_buttonArea, true,   i18n( "Measure the area of a circle" )  );
	measure->insertButton( UserIcon("angle"), ID_buttonAngle, true,   i18n( "Measure an angle in degree" )  );
	measure->insertButton( UserIcon("slope"), ID_buttonSlope, true,   i18n( "Measure the slope between two points" )  );
	measure->insertButton( UserIcon("circumference"), ID_buttonCircumference, true,   i18n( "Measure the circumference of a circle" )  );
	measure->setFullSize( false );

	KToolBar *tools = new KToolBar( this, QMainWindow::Right, false );
	tools->insertButton( UserIcon("pointer"), ID_buttonPointer, true,   i18n( "Go to drag mode" )  );
	tools->insertButton( UserIcon("moveGrid"), ID_buttonMoveGrid, true,   i18n( "Move the underlying grid" )  );
  tools->insertSeparator();
  tools->insertLineSeparator();
  tools->insertSeparator();
	tools->insertButton( UserIcon("eraser"), ID_buttonEraser, true,   i18n( "Erase an object and all of its child objects" )  );
	tools->insertButton( UserIcon("attacher"), ID_buttonAttacher, true,   i18n( "Attach a point on a line/circle" )  );
	tools->insertButton( UserIcon("tracer"), ID_buttonTracer, true,   i18n( "Toggle trace" )  );
	tools->insertButton( UserIcon("text"), ID_buttonText, true,   i18n( "Add a text field" )  );
  tools->insertSeparator();
  tools->insertLineSeparator();
  tools->insertSeparator();
	tools->insertButton( UserIcon("paint"), ID_buttonDrawColor, true,   i18n( "Apply current color to an object" )  );
	tools->insertButton( UserIcon("sizer"), ID_buttonSizer, true,   i18n( "Apply current size to an object" )  );
	tools->setFullSize( false );

  bg = new QButtonGroup( this );
  bg->hide();
  bg->setExclusive( true );

	for ( int i = ID_buttonPoint; i <= ID_buttonRotation; i++ )
	{
		point->setToggle ( i, true );
		bg->insert( point->getButton( i ), i );
  }
	for ( int i = ID_buttonSegment; i <= ID_buttonTriangle; i++ )
	{
		line->setToggle ( i, true );
		bg->insert( line->getButton( i ), i );
  }
	for ( int i = ID_buttonBaseCircle; i <= ID_buttonArc; i++ )
	{
		circle->setToggle ( i, true );
		bg->insert( circle->getButton( i ), i );
  }
	for ( int i = ID_buttonDistance; i <= ID_buttonCircumference; i++ )
	{
		measure->setToggle ( i, true );
		bg->insert( measure->getButton( i ), i );
  }
	for ( int i = ID_buttonEraser; i <= ID_buttonSizer; i++ )
	{
		tools->setToggle ( i, true );
		bg->insert( tools->getButton( i ), i );
  }

  connect( bg, SIGNAL( clicked( int ) ), this, SLOT( toolBar2Clicked( int ) ) );
}

void KGeoApp::initStatusBar()
{
  ///////////////////////////////////////////////////////////////////
  // STATUSBAR
  // TODO: add your own items you need for displaying current application status.
	statusBar()->setFixedHeight( 25 );
	statusBar()->insertItem( i18n( " Welcome to KGeo" ), 1, 10 );
  statusBar()->insertFixedItem( " x = 0.00 : y = 0.00            ", 2, 1 );
	statusBar()->setItemAlignment ( 1, AlignLeft | AlignVCenter );
	statusBar()->setItemAlignment ( 2, AlignLeft | AlignVCenter );

  QColor drawColor, backgroundColor;
 	kapp->config()->setGroup( "Colors" );

	if ( kapp->config()->hasKey( "Draw" ) )
	{
		drawColor	= kapp->config()->readColorEntry( "Draw" );
	}
	else
	{
		drawColor	= Qt::black;
		kapp->config()->writeEntry( "Draw", drawColor );
	}

	if ( kapp->config()->hasKey( "Background" ) )
	{
		backgroundColor = kapp->config()->readColorEntry( "Background" );
	}
	else
	{
		backgroundColor	= Qt::white;
		kapp->config()->writeEntry( "Background", backgroundColor );
	}

	colorLabel = new ColorLabel( drawColor, backgroundColor, statusBar() );
	colorLabel->setFixedWidth( 25 );
	colorLabel->setFixedHeight( 16 );
	statusBar()->addWidget( colorLabel );
  connect( colorLabel, SIGNAL( backgroundColorChanged( QColor ) ), this, SLOT( setBackgroundColor( QColor ) ) );
  connect( colorLabel, SIGNAL( drawColorChanged( QColor ) ), this, SLOT( setDrawColor( QColor ) ) );
  QToolTip::add( colorLabel, i18n( "Choose draw or background color" ) );
}

void KGeoApp::startSplashScreen()
{	
	kapp->config()->setGroup( "Startup" );
	bool splashscreen = kapp->config()->readBoolEntry( "Splashscreen", true );

	if ( splashscreen )	
	{
		SplashScreen *splash = new SplashScreen();
		splash->exec();
		delete splash;
	}
}
