#ifndef IMAGEWINDOW_H
#define IMAGEWINDOW_H

#include <qimage.h>
#include <qmainwindow.h>
#include <qmutex.h>

#include <qscrollview.h>

#include "transactionthread.h"
#include "mainCC3D.h"
#include <map>
#include <string>
#include <fstream>
#include "Projection2DData.h"

#include "GraphicsBase.h"
#include "UniversalGraphicsSettings.h"
#include "ScreenshotData.h"
#include "ScreenshotDescription.h"

class QAction;
class QLabel;
class QPainter;
class QPushButton;
class QToolBar;
class QRadioButton;
class QHButtonGroup;
class QSpinBox;
class QCheckBox;
class QComboBox;
class QHGroupBox;
class QLineEdit;
class QLCDNumber;
class Display3D;
class QSemaphore;



class ImageWindow : public QMainWindow
{
    Q_OBJECT
public:
    ImageWindow(QWidget *parent = 0, const char *name = 0,bool _silent=false);
    ~ImageWindow();
   void startSimulation();
   void setXMLFile(const QString &fileName);   
   void setScreenshotDescriptionFileName(const QString & scrDesFileName);
    
protected:
    void closeEvent(QCloseEvent *event);
    void customEvent(QCustomEvent *event);

private slots:
    void open();
    bool saveScrDes();
    
    void simulation();
    void simulationPause();
    void zoomIn();
    void zoomOut();
    
    ///projections and 3D
    
    void changeProjectionXY(bool);
    void alterZCoordinate(int);
    void changeProjectionXZ(bool);
    void alterYCoordinate(int);
    void changeProjectionYZ(bool);
    void alterXCoordinate(int);

    void switch3D(bool);
    
    void bordersDisplay(bool);
    void contoursDisplay(bool);
    void concentrationLimitsDisplay(bool);
    
    void frequencyUpdate(int);
    void plotTypeUpdate( const QString &);

    
    void configureColors();
    void configureColorMapPlot();
    void configureVectorFieldPlot();
    void configureScreenshotFrequency();
    void configureTypes3DInvisible();
    void configureCellTypeColors();
    void configure3DDisplay();
    void saveSettings();
    void about();

   void addScreenshot();
    
private:
    const unsigned int maxScreenshotListLength;
    const QString screenshotCoreName;
    QString screenshotDescriptionFileName;

    void initProjectionXYData();
    void initProjectionXZData();
    void initProjectionYZData();
    
    void createActions();
    void createMenus();
    void createSteeringBar();
    void createStatusBar();

    void saveScrDesFile(const QString &fileName);
    void setCurrentFile(const QString &fileName);
    QString strippedName(const QString &fullFileName);
    void addTransaction(Transaction *transact);

    void drawField();
    void drawField2D();
    void drawField3D();
    QString screenshotName();

    void (ImageWindow::*draw)();

    void outputScreenshot();       
    void writeSettings();
    void readSettings();
    void readScreenshotDescriptionList(std::list<ScreenshotDescription> & _screenshotDescriptionList, const std::string &fileName);
    void produceScreenshotDataList(const std::list<ScreenshotDescription> & _screenshotDescriptionList);
    QPainter *painter;

    std::list<ScreenshotData*> screenshotDataList;
    std::list<ScreenshotDescription> screenshotDescriptionList;
    
    std::vector<GraphicsBase *> graphicsPtrVec;
    
    GraphicsBase *currentGraphicsPtr;
    GraphicsBase * display3D;

    GraphicsBase * graphics2DPtr;
    
    Projection2DData *projDataPtr;

    GraphicsDataFields * graphFieldsPtr;
        
    unsigned int screenshotCounter;
    std::string imageCoreFileName;
    std::string imageFileExtension;

    QScrollView *scrollView;
    
    ///Mutexes  
    QMutex mutex;
    QMutex mutexStartPause;
    QMutex mutexFieldDraw;
    QMutex mutexTransaction;

    QSemaphore * bufferFillUsedSemPtr;
    QSemaphore * bufferFillFreeSemPtr;

    
    TransactionThread thread;
    //steering bar buttons
    QToolBar * steeringBar;
    QRadioButton *xyButton, *xzButton , *yzButton;
    QHButtonGroup *crossSectionButtonsG;

    QPushButton *updateViewButton;
    
    QSpinBox *xSpinBox;
    QSpinBox *ySpinBox;
    QSpinBox *zSpinBox;
    Projection2DData xyProjData;
    Projection2DData xzProjData;
    Projection2DData yzProjData;

    QRadioButton *display3DButton;

    QPushButton * recordButton;
    

    QHGroupBox *zoomBox;
    unsigned int screenshotFrequency;
    
    ///treshold box
    QLabel *minMaxConcentrationLabel;

    
    QComboBox *plotTypeComboBox;
    QLabel *plotTypeComboBoxName;

    ///MC Step
    QLabel *mcStepLabel;
       
    //QLabel *imageLabel;
    QLabel *infoLabel;
    QLabel *modLabel;
    QCString imageFormat;
    QString curFile;
    QString curFileStripped;
    QString tmpDirName;
    QString inventoryFileName;
    QString simulationRootDir;
    std::ofstream inventoryFile;
    
    bool modified;
    bool drawingAllowed;
    ///Popup Menus  
    
    ///File  
    QPopupMenu *fileMenu;
    QAction *openAct;
    QAction *saveScrDesAct;
    QAction *exitAct;
    

    ///configure
    QPopupMenu *configureMenu;
    QAction * typeColorAct;
    QAction *colorMapPlotAct;
    QAction *vectorFieldPlotAct;
    QAction *screenshotFrequencyAct;
    QAction * types3DInvisibleAct;
    QAction * configure3DDisplayAct;
    
    QAction * saveSettingsAct;
    
    ///simulation   
    QPopupMenu *simulationMenu;
    QAction *simulationAct;
    QAction *simulationPauseAct;
    

        
    ///zoom  
    QPopupMenu *zoomMenu;
    QAction *zoomInAct;
    QAction *zoomOutAct;

    ///show  
    QPopupMenu *showMenu;
    QAction *showBordersAct;
    QAction *showContoursAct;
    QAction *showConcentrationLimitsAct;
    
    
    ///help    
    QPopupMenu *helpMenu;
    QAction *aboutAct;
    QAction *aboutQtAct;
    
   ///universal settings - i.e. valid for 2D and 3D drawing
   UniversalGraphicsSettings univGraphSet;
   
   float minConcentration;
   bool minConcentrationFixed;
   float maxConcentration;
   bool maxConcentrationFixed;
   unsigned int numberOfLegendBoxes;
   unsigned int numberAccuracy;
   bool legendEnable;
   
   float minMagnitude;
   bool minMagnitudeFixed;
   float maxMagnitude;
   bool maxMagnitudeFixed;
   float arrowLength;
   unsigned int numberOfLegendBoxesVector;
   unsigned int numberAccuracyVector;
   bool legendEnableVector;
   
   ScreenshotData *scshData;
   ScreenshotData *scshData1;
   bool silent;
    
};

#endif
