/*
 * DuneApp.h
 *
 * Copyright (C) 1999 Stephen F. White
 * 
 * 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 (see the file "COPYING" for details); if 
 * not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
 * Cambridge, MA 02139, USA.
 */

// data global to the whole application

#ifndef _DUNE_APP_H
#define _DUNE_APP_H

// time between 2 frames in best case in milliseconds
#define FRAME_DELAY 70

#ifndef _LIST_H
#include "List.h"
#endif
#ifndef _ARRAY_H
#include "Array.h"
#endif
#ifndef _DUNE_STRING_H
#include "MyString.h"
#endif
#ifndef _NODE_H
#include "Node.h"
#endif
#ifndef _URL_H
#include "URL.h"
#endif
#ifndef _PREFERENCES_APP_H
#include "PreferencesApp.h"
#endif
#ifndef _ECMASCRIPT_APP_H
#include "EcmaScriptApp.h"
#endif
#ifndef _STEREO_VIEW_APP_H
#include "StereoViewApp.h"
#endif
#ifndef _INPUT_DEVICE_APP_H
#include "InputDeviceApp.h"
#endif
#ifndef _OUTPUT_APP_H
#include "OutputApp.h"
#endif
#ifndef _INPUT_APP_H
#include "InputApp.h"
#endif
#ifndef _ROUTE_VIEW_APP_H
#include "RouteViewApp.h"
#endif
#ifndef _START_WITH_APP_H
#include "StartWithApp.h"
#endif
#ifndef _EXPORT_NAMES_APP_H
#include "ExportNamesApp.h"
#endif

#include <GL/gl.h>

class Scene;
class MainWindow;

class FileBackup { 
public:
                  FileBackup(char* backupFile, URL url, const char* path);

    char         *_backupFile;
    URL           _url;
    char*         _path;
};       

class DuneApp : public PreferencesApp, 
                public EcmaScriptApp, 
                public StereoViewApp, 
                public InputDeviceApp,
                public OutputApp,
                public InputApp,
                public RouteViewApp,
                public StartWithApp,
                public ExportNamesApp {
public:
                        DuneApp();

    void                initPreferences(void);

    // file menu
    void                newMainWnd(SWND &mainWnd);
    void                OnFileNew(bool x3d = false);
    void                OnFileNewWindow();
    void                OnFilePreview(Scene* scene);
    void                OnFileUpload(Scene* scene);
    void                OnFileEdit(MainWindow *window, Scene* oldscene,
                                   char* filename=NULL);
    void                OnFileClose(MainWindow *window);
    void                OnFileExit();

    bool                ImportFile(const char *openpath, Scene* scene, 
                                   bool protoLibrary = false, 
                                   Node *node = NULL, int field = -1);
    bool                AddFile(char* openpath, Scene* scene);
    char *              SaveTempFile(Scene *scene, const char *name, 
                                     int writeFlags);
    bool                OpenFile(const char *path);

    void                reOpenWindow(Scene* scene);
    bool                checkSaveOldWindow(void);
    void                deleteOldWindow(void);

    // recent files in File menu 
    int                 GetNumRecentFiles() const;
    const MyString     &GetRecentFile(int index) const;
    void                AddToRecentFiles(const MyString &filename);
    void                SaveRecentFileList(void);

    int                 emergency_rescue(int sig = -1);


    SBROWSER            GetBrowser() const { return _browser; }
    SHBROWSER           GetHelpBrowser() const { return _helpBrowser; }
    STEXTEDIT           GetTextedit() const { return _textedit; }
    SUPLOAD             GetUpload() const { return _upload; }

    Node               *getClipboardNode(void) { return _clipboardNode; }
    void                setClipboardNode(Node* node) { _clipboardNode = node; }
    void                removeClipboardNode(Node* node) 
                           {
                           if (_clipboardNode == node) 
                              _clipboardNode = NULL; 
                           }

    SWND                mainWnd(void) {return _mainWnd;}

    void                PrintMessageWindows(const char *text);
    void                PrintMessageWindowsId(int id);
    void                PrintMessageWindowsInt(int id, int integer);
    void                PrintMessageWindowsFloat(int id, float f);  
    void                PrintMessageWindowsString(int id, const char *string);
    void                PrintMessageWindowsVertex(int id, 
                                                  const char *fieldName, 
                                                  int vertex);

    char               *loadPrompt(int prompt);
    void                MessageBox(const char *text, int prompt = -1);
    void                MessageBoxId(int id, int prompt = -1);
    void                MessageBox(int id, const char *str, int prompt = -1);
    void                MessageBox(int id, const char *str1, const char *str2,
                                   int prompt = -1);
    void                MessageBox(int id, int integer, int prompt = -1);
    void                MessageBox(int id, float f, int prompt = -1);
    void                MessageBoxPerror(const char *object);
    void                MessageBoxPerror(int id, const char *object);

    void                AddToFilesToDelete(char* string); 

    const char         *getImportURL(void) { return _importURL; }
    void                setImportURL(const char* newURL) { _importURL=newURL; }

    void                initSelectionLinenumber(void); 
    void                checkSelectionLinenumberCounting(Scene* scene, 
                                                         Node* node);
    void                incSelectionLinenumber(int increment = 1);
    int                 getSelectionLinenumber(void);

    bool                saveTempFiles(MainWindow *currentWindow, 
                                      int useExtensionTxt);
    void                restoreTempFiles(void);

    void                UpdateAllWindows(void);

    List<MainWindow *>  getWindows(void) { return _windows; }
    bool                hasUpload(void);

    void                addToProtoLibrary(char* category, char* protoFile);
    bool                readProtoLibrary(Scene* scene);
#ifdef HAVE_OLPC
    bool                isOLPC(void) { return true; } 
#else
    bool                isOLPC(void) { return false; } 
#endif
    bool                is4Kids(void) { return _is4Kids; }
    void                set4Kids(void) { _is4Kids = true; }
    bool                is4Catt(void) { return _is4Catt; }
    void                set4Catt(void) { _is4Catt = true; }
    bool                getX3dv(void) { return _x3dv; }
    void                setX3dv(void) { _x3dv = true; }
    bool                dontCareFocus(void) { return _dontCareFocus; }
    void                setDontCareFocus(void) { _dontCareFocus = true; }
    bool                loadNewInline(void);
    void                setCoverMode(void) { _coverMode = true; }
    bool                getCoverMode(void) { return _coverMode; }
    void                setKambiMode(void) { _kambiMode = true; }
    bool                getKambiMode(void) { return _kambiMode; }
    bool                GetNormalsOnPureVRML97() const
                           {
                           if (_coverMode)
                               return true;
                           return OutputApp::GetNormalsOnPureVRML97(); 
                           }
     void               setFileDialogDir(char *dir) { _fileDialogDir = dir; }
     char              *getFileDialogDir(void) { return _fileDialogDir; }
     bool               getCreateAtZero(int i) { return _createAtZero[i]; }
     void               setCreateAtZero(int i, bool f) { _createAtZero[i] = f; }
     bool               browseCommand(char *buf, int len, int ids_text);
     bool               checkCommand(const char *command, 
                                     bool checkForFile = true);
     void               checkAndRepairTextEditCommand(void);
     void               checkAndRepairImageEditCommand(void);
     void               checkAndRepairImageEdit4KidsCommand(void);
     void               checkAndRepairSoundEditCommand(void);
     void               checkAndRepairMovieEditCommand(void);

     bool               getBlackAndWhiteIcons(void) 
                           { return _blackAndWhiteIcons; }
     void               setBlackAndWhiteIcons(void) 
                           { _blackAndWhiteIcons = true; }

    int                 getTessellation(void)
                            { return _defaultTessellation; }
    void                setTessellation(int tessellation)
                            { _defaultTessellation = tessellation; }

    void                printRenderErrors(GLenum error);
    int                 printRenderErrors(bool printOnOutOfMemory = true);

    bool                getVrml1Error(void) { return _vrml1Error; }
    void                setVrml1Error(void) { _vrml1Error = true; }

    int                 searchIllegalChar(char *id);

    void                setDefaults(void);

    bool                getDemoMode(void) { return _timeOut != -1; }
    void                setDemoMode(int timeOut) { _timeOut = timeOut; }

    bool                getRenderFaster(void)
                            { return _renderFaster; }
    void                SetRenderFaster(bool s)
                            { _renderFaster = s; }

    void                interact(void);
    bool                timeOut(void);

protected:
    void                Exit(void);

protected:
    List<MainWindow *>  _windows;
    Array<MyString>     _recentFiles;

    SBROWSER            _browser;
    SHBROWSER           _helpBrowser;
    STEXTEDIT           _textedit;
    SUPLOAD             _upload;

    SWND                _mainWnd;
    Node               *_clipboardNode;

    Array<MyString*>    _filesToDelete;

    const char*         _importURL;

    int                 _selectionLinenumber;
    bool                _selectionLinenumberFlag;

    List<FileBackup *>  _tempFiles;

    bool                _coverMode;
    bool                _kambiMode;

    const char         *_keyProtoFile;
    const char         *_keyProtoCategory;
    bool                _is4Kids;
    bool                _is4Catt;
    bool                _x3dv;
    bool                _dontCareFocus;
    int                 _numberLoadedInlines;
    char               *_fileDialogDir;
    bool                _createAtZero[3];
    bool                _blackAndWhiteIcons; 
    int                 _defaultTessellation;
    int                 _glErrorCount;
    MainWindow         *_currentWindow;
    bool                _vrml1Error;
    int                 _timeOut;
    bool                _timeOutSet;
    int                 _lastInteraction;
    bool                _renderFaster;
};

extern DuneApp *TheApp;

#endif // _DUNE_APP_H
