/***************************************************************************
 *   Copyright (C) 2004 by Juergen Thies                                   *
 *   layout@juergenthies.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 LAYOUT_H
#define LAYOUT_H
/**
@author Juergen Thies
*/
#ifdef WINDOWS
#ifdef OPENACCESS
#include <winsock2.h>
// #define _WINSOCKAPI_
#endif
#endif
#include <QMainWindow>
#include <QResizeEvent>
#include <QCloseEvent>
#include <QMap>
#include "general/drawingfield.h"
#include "widgets/layerbutton.h"
#include "widgets/layertool.h"
#include "widgets/selectwidget.h"
#include "widgets/gridwidget.h"
#include "widgets/timewidget.h"
#include "widgets/poswidget.h"
#include <qcombobox.h>
#include <qprinter.h>
#include "general/setup.h"
#include "general/errorreport.h"
#include "widgets/lineedit.h"
#include "general/reportview.h"
#include <QThread>
#include <QWaitCondition>
#include "widgets/mainwindow.h"
#include "widgets/newcombobox.h"
#include "general/setup.h"
#ifdef barcodeutility
class barcodeModule;
#endif
#ifdef USE_3d
 class view3dModule;
#endif
#ifdef TEXTEDIT
 class textEdit;
#endif
#ifdef OPENACCESS
 class oaModule2;
#endif
#ifdef backgroundutility
class backgroundModule;
#endif
enum viewModeType {	viewermode, basicmode , intermediatemode, fullmode, defaultmode,custommode, genisysmode,genisysmodenoopen,puremode};

class guiWorkThread;
class mouseHelp;
class booleanHandler;
class helpWindow;
class setupWindow;
class drc;
class gridwidget;



//#define deleteAktuellCell deleteActuellCell
//! main widget class
/*!
  This class is the main widget of the windows from which the macro was executed. It is directly accessible via the classname "layout".
  @code
  layout->filename="/var/layouts/samples1.gds";<br>
  layout->newCell();
  @endcode 
  Most methods of this call require a user dialog. A direct access of the drawing is possible via the member drawing. 
  @link "Class drawingField;drawingField"
*/
class layout: public mainWindow
{
    Q_OBJECT

public:
    QToolBar *commandLineTools;
    
    mouseHelp *mouseHelps;
    setupWindow *setup;
private: 
    layerTool *layerTools;
  
    viewModeType viewMode;
    newComboBox *cellcombo;
    newComboBox *gridcombo;
    int macroMultiButton;
    void spezialToolbar(int num);
    virtual void getFunctionInfo(int function, QString *textLabel, QObject ** receiver, const char ** slot,helpText *helptext);
    selectwidget *selectStatus;
    gridwidget *gridStatus;
    timewidget *timeStatus;
    poswidget *posStatus;
    bool userGridChange;
    lineEdit *commandLine;
    void *guiThread;
signals:
    void lastFilesAdd(QString);
    void updateGui();
//! signal current cell changed
/*!
This signal is emitted when the current displayed cell has changed.
@nomacro
*/ 
    void newCurrentCell(const QString &s);
//! signal closed
/*!
This signal is emitted when the window is closed and destroyed
@nomacro
*/
    void closed();
//! signal cells change
/*!
This signal is emitted when cells has been added or deleted.
@nomacro
*/ 
  void cellsChanged(QStringList list,QString currentCell );
public:
    void setCellCombo(QString);
    guiWorkThread *workThread;
#ifdef barcodeutility
//! barcode tool
/*!
The barcode utilities are accessible via this class.
*/
    barcodeModule *barcodeTool;
#endif
#ifdef backgroundutility
//! background tool
/*!
The background utilities are accessible via this class.
*/
    backgroundModule *backgroundTool;
#endif
#ifdef USE_3d
//! view 3d tool
/*!
The 3d view is accessable via this class
*/
    view3dModule *view3dTool;
#endif
#ifdef OPENACCESS
    oaModule2 *oaTool;
#endif
//! boolean tool
/*!
The boolean utilities are accessible via this class.
@link "Class booleanHandler;booleanHandler"
*/
    booleanHandler *booleanTool;
//! design rule checker tool
/*!
The design rule checker is accessible via this class.
@link "Class drc;drc"
*/
    drc *drcTool;
 //   bool viewonly;
//! head class of the drawing
/*!
This class is the main class of the drawing. It holds all relevant information. 
@link "Class drawingField;drawingField"
*/
    drawingField *drawing;

//!filename
/*!
This string hold the current filename.
*/ 
     QString filename;
    layout(viewModeType viewonly=fullmode);
    ~layout();
//! layout
/*!
Creates a new layout window
@nomacro
*/ 
//-    layout();
protected:
    void closeEvent( QCloseEvent* );
    void resizeEvent ( QResizeEvent * );
    void keyPressEvent ( QKeyEvent * event );
    void keyReleaseEvent ( QKeyEvent * event )  ;
    void windowActivationChange ( bool oldActive );
public slots:
	void commandlineActivate();
private:
	bool commandlineTab;
    int snapToPointButton,snapToGridButton, snapToMiddleButton,snapToLineButton, snapToCenterButton, snapToIntersection;
private slots:
// ---- slots for GUI
    void chooseUserunits();
    void toggleSnapToGrid(){if (snapToGridButton!=0) singleButton[snapToGridButton]->processClick();};
    void toggleSnapToPoint(){if (snapToPointButton!=0) singleButton[snapToPointButton]->processClick();};
    void toggleSnapToMiddle(){if (snapToMiddleButton!=0) singleButton[snapToMiddleButton]->processClick();};
    void toggleSnapToLine(){if (snapToLineButton!=0) singleButton[snapToGridButton]->processClick();};
    void toggleSnapToCenter(){if (snapToCenterButton!=0) singleButton[snapToCenterButton]->processClick();};
    void toggleSnapToIntersection(){if (snapToIntersection!=0) singleButton[snapToIntersection]->processClick();};
    void nextLayout();
    void invertSelect();
    void selectAll();
    void selectVisible();
    void deselectAll();
    void deSelectAll();
    void selectActiveLayer();
    void deselectActiveLayer();
    void pathSelect();
    void pathDeselect();
    void boxSelect(); 
    void boxDeselect();
    void polygonSelect(); 
    void polygonDeselect();
    void textSelect();
    void textDeselect();
    void mergeSelect();
    void deleteSelect();
    void cropWithSelection();
    void toBox();
    void toPolygon();
    void toCircle();
    void closedPathToPolygon();
    void copyCurrentCell();
    void undo();
    void redo();
    void clipboardCopy();
    void clipboardPaste();
    void screenshotGui();
    void chooseImportGui();
    void chooseUpdateGui();
    void chooseGui();
    void openImportGui();
    void openImportUpdateGui();
    void saveGui();
    void saveAsGui();
    void saveAsSaveGui();
    void printGui();
    void setCellnameGui();
    void newCellGui();
    void deleteActuellCellGui();
    void flat();
    void flatAll();
    void setCellGui();
    void emitNewCurrentCell(const QString &s);
    void groupGui();
    void groupSimpleGui();
    void groupStructureGui();
    void groupGlobalGui();
    void commandLineEnter();
    void areaSelect();
    void extractCell();
    void extractLayer();
    void stripUnneeded();
    void stripEmptyCells();
    void removeScaledCellref();
    void removeCellArrays();
    void removeNotOrthogonalCellref();
    void copyLayer();
    void moveLayer();
    void moveBy();
    void copyBy();
    void gotoxy();
    void modifyCorners();
    void toMeshSelect();
    void sizeadjustSelect();
    void roundSelect();
    void snapShapesSelect();
    void edgeRemoveSelect();
    void cropSharpAnglesSelect();
    void stripIdenticalElements();
    void openLayerManager();
    //drc
    void drcMinDistance();
    void drcInside();
    void drcGrid();
    void drcMinSize();
    void drcMinOverlap();
    void drcMinElementDistance();
    void drcMinDistanceOrOverlap();
    void drcLayerCombination();
    void drcEnclosure();
    void drcOverlapDistance();
    void drcDimension();
    void drcNoHoles();
    void drcAngles();
    void drcArea();
    void drcPerimeter();
    void drcNotches();
//-----
public slots:
//! open file
/*!
A file with the name fileName is opened.If the prevous design was change it is asked to save it.
@nomacro
*/
    void open(QString fileName);
    void closeDesignGui();
//! close design
/*!
The current design will be removed and an empty design is shown like after the program start.
*/
    void closeDesign();
    void setStatusBarSize(int width);
    void toggleMenu();
    void newDoc();
    void openSchematic();
    void chooseUpdate();
    void showGridToggle();
    void setTitle(QString s);
    void zeigeString(QString s);
    void zeigeMousePos(QPoint pos);
    void zeigeDifPos(QPoint pos,QPoint dif);
    QString getUserunits();
    void setUserunits(QString s);
    void aktiveLayerChange(int nr);
    void paint(){drawing->paint();}
    void cellsUpdate();
    void currentCellUpdate();
    void addCellref();
    void addCellrefArray();
    void selectCellref();
    //menubar
    void showMenuBar();
    void hideMenuBar();
    bool isMenuBarVisible();
    //macro
    void macroStart(QString,QString);
    void macroAdd(QString s){drawing->macroAdd(s);}
    void startMacroRecording();
    void stopMacroRecording();
    void generateTechnologyMacro();
    void generate3dSetupMacro();
    void generateViewMacro();
    void executeMacroGui();
    void editMacroGui();
    //grid
    void gridChange(const QString &s);
    void gridPlus();
    void gridMinus();
    void gridAuto();
    void gridAutoPlusMinus();
    void updateGrid();
    void setGrid();
    //layer
    void updateLayerbutton();
    void updateSetupLayerbutton();
    //debug
    void debugOnOff();
    void cleanElements();
    void compareCell();

    void hideUnusedLayers();
    void hideCurrentUnusedLayers();
    void disableUnusedLayers();
    void enableAllLayer();

//! trigger 3d render all
/*!
renderAll will be called after the macro terminates.
OBSOLETE: Please use view3dTool->trigger3dRenderAll() instead.
*/
    void trigger3dRenderAll();
//! trigger 3d render select
/*!
renderSeclect will be called after the macro terminates.
OBSOLETE: Please use view3dTool->trigger3dRenderSelect() instead.
*/
    void trigger3dRenderSelect();
//! trigger 3d render auto
/*!
renderAuto will be called after the macro terminates.
OBSOLETE: Please use view3dTool->trigger3dRenderAuto() instead.
*/
    void trigger3dRenderAuto();
    void screenshot3d();
    void renderAll();
    void renderSelect();
    void renderAuto();
    void renderOff();
    void screenshot3dGui();
    void setup3d();

public:
// lock GUI
    QMutex lockMutex;
    QWaitCondition lockWait;
    bool guiLocked;
public slots:
// lock GUI

    void lockGuiThread();
    void unlockGuiThread();
// guiThreadfunction for workthread dialogs
    void askSaveModifications();
    void askOpenFilename();
    void askSaveFilename();
    void askPrint();
    void askText(QString,QString,QString);
    void askDouble(QString,QString,double,int);
    void askInteger(QString,QString,int);
    void askBool(QString,QString);
    void askShowMessage(QString,QString);
    void askCell();
    void askScreenshot();
    void askCellName();
    void askTextEditor();
    bool isGuiThread(){   
		void *v=QThread::currentThread ();
    		if (v==guiThread) return true;
		else return false;}
    void showLastReport(){errorreport::showLastReport();}
    void showReport(QString s,int rang){  if (rang<=setup::showReport) {
 		 			reportview r(s);
 		 			r.exec();
		 			}}
    
//-------
private:
    void setFileName(QString oldName,QString newName);



public:
//! set cell
/*!
You will be prompted to select a cell. The cell will be displayed.
*/ 
    void setCell();
//! set cellname
/*!
You will be prompted to enter a name for the current displayed cell.
*/ 
    void setCellname();  
  
//! execute macro
/*!
Another macro is executed. The execution of this macro stopped until the termination of the new started macro.
@param filename	filename of the macro.
*/ 
    int executeMacro(QString filename, QString parameter="");
    int executeMacroForce(QString filename, QString parameter="");
//! file open
/*!
It opened a file dialog. The selected file will be loaded.
*/ 
    void choose();
//! file import
/*!
It opened a file dialog. The selected file will be imported.(= add to the existing file)
*/ 
    void chooseImport();
//! file save
/*!
The actual file will be saved. If filename is empty, you will be prompted to enter a filename.
*/ 
    void save();
//! file save as
/*!
You will be prompted to enter a filename. The actuell file will be saved.
*/ 
    void saveAs();
//! screenshot
/*!
The screen will be saved. You will be prompted to enter a filename.
*/ 
    void screenshot();
//! print
/*!
A printer dialog will be opened.
*/ 
    void print();


//##########################################################################################
//obsolete features

//! screenshot
/*!
The screen will be saved in the file with the name filename. The type is selected by the extension.
OBSOLETE: Please use drawing->saveScreenshot(QString filename) instead.
*/ 
    void saveScreenshot(QString filename){drawing->saveScreenshot(filename);};
//! group selected elements
/*!
All selected elements are moved to a new cell. A correlating cellref will be added.
OBSOLETE: Please use drawing->group() instead.
*/ 
    void group();
//! delete 
/*!
After a confirmation the current display cell will be deleted. If there are no more cell in the drawing, a new empty cell will be created.
OBSOLETE: Please use drawing->deleteCurrentCell() instead.
*/ 
    void deleteActuellCell();
//! new cell
/*!
A new empty cell will be added, named with an unused cell name and it is set as current cell.
OBSOLETE: Please use drawing->newCell() instead.
*/ 
    void newCell(){drawing->newCell();};
  
    
    
//##########################################################################################
//dialogs
public slots:  
  void execute2Macro(QString filename){ executeMacro(filename);}
//! get text
/*! 
The user will be prompted to enter a text.
@param caption	the title of the window.
@param lable 	this string will be displayed inside the window.
@param value	default value
@return returns the text set by the user.*/
   QString getText(QString caption,QString lable,QString value="");
//! get integer
/*!
The user will be prompted to enter a integer.
@param caption 	the title of the window.
@param lable 	this string will be displayed inside the window.
@param value	default value
@return returns the integer set by the user.
*/
   int getInteger(QString caption,QString lable, int value=0);
//! get double
/*!
The user will be prompted to enter a double.
@param caption 	the title of the window.
@param lable 	this string will be displayed inside the window.
@param value	default value
@param digis	maximal number of digits 
@return returns the double set by the user.
*/    
   double getDouble(QString caption,QString lable,double value=0, int digits=1);
//! get bool
/*!
The user will be prompted to enter a bool.
@param caption 	the title of the window.
@param lable 	this string will be displayed inside the window.
@return returns 0 if yes, otherwise 1
*/    
   int getBool(QString caption,QString lable);
//! get open filename
/*!
A file open dialog is shown.
@return returns a string with the filename or a empty string if canceled
*/
   QString getOpenFilename();
//! get save filename
/*!
A file save dialog is shown.
@return returns a string with the filename or a empty string if canceled
*/
   QString getSaveFilename();
//! show message in statusbar
/*!
A message will be displayed in the statusbar for 2 seconds.
@param lable 	this string will be displayed in the statusbar.
*/
   void showStatus(QString lable);
//! show message
/*!
A message will be displayed.
@param caption	the title of the window.
@param label	this string will be displayed inside the window.
*/
   void showMessage(QString caption,QString label);
#ifdef TEXTEDIT
//! show text editor
/*!
Will create a new text Editor window in a thread save way.
*/
   textEdit* showTextEditor();
#endif
//##########################################################################################
//Gui setup
  public:
//! set shortcut
/*!
Use this function to modify any existing shortcut. It returns true, if the modification was successful.
@code
		layout->setShortcut("&Sector",""); // remove old 'F' shortkey <br>
		layout->setShortcut("&Zoom Fit All","F"); // set 'F' to zoom fit<br>
		layout->setShortcut("&Zoom Fit Selection","Shift+F"); // set 'Shift F' to zoom fit selection<br>
@endcode

*/    
//-   bool setShortcut(QString function,QString key); 
//! add command line dock
/*!
Add a c/cpp commandline macro dock and make it invisible.
@nomacro
*/ 
   void addCommandLineDock();
//! add mouse help dock
/*!
Add a mouse help dock to the window and adds it to the left dock.
@nomacro
*/ 
   void addMouseHelp();
// ! add layer dock
/* !
Add a layer dock to the window and adds it to the left dock.
Add a layer menu to the main menu.
@nomacro
*/ 
   void addLayerDock(); 
    
//! add 3d view dock
/*!
Add a c/cpp companndline macro dock and make it invisible.
@nomacro
*/ 
   void add3dDock();
//! hide tool bar
/*!
Hides the named toolbar. 
*/ 
   void hideToolBar(QString name);
//! show tool bar
/*!
Shows the named toolbar. 
*/ 
   void showToolBar(QString name);
//! add tool bar
/*!
Add a new tool bar, separate multipli buttons with a ';'.
@code 
	layout->toolBarAdd("my toolbar","New Layout;Zoom Mouse;Code 39;Quit");
@endcode
*/ 
   void toolBarAdd(QString name,QString buttons );
//! last toolbar
/*!
@return a pointer to the last created toolBar
@nomacro
*/ 
   QToolBar * toolBarLast(){return toolBar[toolBarNext];}
//! add menu
/*!
Add a new entry to the main menu. The first parameter is the name of the menu. The second parameter contains last entries of the new menu seperated with a semicolon.
@nomacro
*/ 
   void menuAdd(QString name,QString entries );
//! get menu
/*!
Returns a point to the menu with the name. If the menu does not exist it will be created. To get submenus use 'mainentry/submenu' as name.
@nomacro
*/ 
//-QMenu *getMenu(QString name);
//! add macros
/*!
Macro in the macro folder will be added to the menu.
@nomacro
*/ 
//- void addMacros();
//! gui Update
/*!
The user interface is updated. It updates the setup of the layerbuttons, the list of existing cell ,.. Call this function after you have changed the design in a script. The c/c++ macro interface call the function automatic after the execution of a macro. 
@nomacro
*/ 
void guiUpdate();
public:
//!debug mode
/*!
True if the debug mode is on.
*/ 
   static bool debug;

   friend class setup;


};


#endif
