/*
 * MainWindow.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.
 */

#ifndef _MAIN_WINDOW_H
#define _MAIN_WINDOW_H

#ifndef _PANED_WINDOW_H
#include "PanedWindow.h"
#endif

#ifndef _SCENE_H
#include "Scene.h"
#endif

#ifdef HAVE_SAND
#include "nebula/ExportNebula.h"
#endif

class SceneView;
class ChannelView;
class ToolbarWindow;
class StatusBar;
class ScriptEdit;
class ObjectEdit;
class ImageTextureEdit;
class PixelTextureEdit;
class MovieTextureEdit;
class AudioClipEdit;
class NodeShape;

#include "swttypedef.h"
#include "ColorConversion.h"
#include "NodeNurbsCurve.h"

enum SiblingCommands {
     MOVE_SIBLING_UP,
     MOVE_SIBLING_DOWN,
     MOVE_SIBLING_FIRST,
     MOVE_SIBLING_LAST
};

class IconPos {
public:
    IconPos(void);
protected:
    int                 GetIconPos(int* buttons,int length,int icon);
    int                 _fileNewIconPos;
    int                 _fileNewX3dIconPos;
    int                 _fileOpenIconPos;
    int                 _fileSaveIconPos;
    int                 _filePreviewIconPos;
    int                 _editCutIconPos;
    int                 _editCopyIconPos;
    int                 _editPasteIconPos;
    int                 _editDeleteIconPos;
    int                 _fullScreenIconPos;
    int                 _colorCircleIconPos;
    int                 _objectEditIconPos;
    int                 _urlEditIconPos;
    int                 _animationIconPos;
    int                 _toNurbs4KidsIconPos;
    int                 _interactionIconPos;
    int                 _x_symetricIconPos;
    int                 _navigationMouseIconPos;
    int                 _mouseExamineIconPos;
    int                 _mouseWalkIconPos;
    int                 _mouseFlyIconPos;
    int                 _mouseRollIconPos;
    int                 _inputModeStartIconPos;
    int                 _tDimensionStartIconPos;
    int                 _t2axesStartIconPos;
    int                 _inputDeviceGreaterIconPos;
    int                 _inputDeviceLesserIconPos;
    int                 _navigationInputDeviceIconPos;
    int                 _xOnlyIconPos;
    int                 _yOnlyIconPos;
    int                 _zOnlyIconPos;
    int                 _showJointLikeHandlesIconPos;
};

class ProtoMenuItem {
public:
    MyString protoName;
    int id;
    bool disabled;
};

class NodeButton {
public:
    int type;
    int id;
    bool alwaysEnabled;
    bool enabled; 
};

class MainWindow : public PanedWindow, IconPos {
public:
                        MainWindow(Scene *scene, SWND parent);

    virtual            ~MainWindow();

    void                destroyMainWindow(void); // but keep scene

    virtual void        OnCommand(int id);
    virtual void        OnHighlight(int id);
    virtual void        OnUpdate(SceneView *sender, int type, Hint *hint);
    virtual void        OnSize(int x, int y);

    const char         *getName(void) const { return "MainWindow"; }

    void                OnFileOpen();
    void                OnFileImport();
    bool                OnFileSave();
    bool                OnFileSaveAs(int writeFlags = 0);
    bool                OnFileExportVRML97();
    bool                OnFileExportX3DV();
    bool                OnFileExportX3DXML();
    bool                OnFileExportX3D4Wonderland();
    bool                OnFileExportCover();
    bool                OnFileExportKanim();
    bool                OnFileExportC();
    bool                OnFileExportCC();
    bool                OnFileExportJava();
    bool                OnFileExportWonderlandModule();
    bool                OnFileExportAc3d();
    bool                OnFileExportAc3d4Raven();
    bool                OnFileExportCattGeo();
    bool                OnFileExportLdrawDat();
    int                 OnTimer();
    bool                SaveModified();
    void                setStatusText(const char *str);
    bool                SaveFile(const char *path, const char *url, 
                                 int writeFlags = 0);

    SWND                getParentWindow() { return _parentWindow; }
    bool                getValidTexture(void);
    bool                isValidNodeType(Node* node, int field);
    void                InitToolbars(void);
    void                InitToolbar(STOOLBAR toolbar, NodeButton *buttons, 
                                    int count);
    void                UpdateToolbars(void);
    void                UpdateToolbar(int id);
    void                UpdateToolbarSelection(void);
    void                UpdateToolbar(STOOLBAR toolbar, Node *node, int field,
                                      NodeButton *buttons, int count);
    void                UpdateMenuVisible(void);
    void                UpdateMenuKambiNodes(void);
    void                UpdateMenuCoverNodes(void);
    void                UpdateStaticMenuCoverNodes(void);
    void                UpdateStaticMenuKambiNodes(void);
    void                UpdateObjectEdit(Node *node);
    void                OnScriptEditorReadyCallback(void);
    void                OnTextEditorReadyCallback(void);
    void                OnImageTextureEditorReadyCallback(void);
    void                OnSoundEditorReadyCallback(void);
    void                OnMovieEditorReadyCallback(void);
    bool                matchFieldPipeFilterNode(Node *node);
    void                matchFieldPipeFilterField(Node *node);
    void                setVrmlCutNode(Node *node) { _vrmlCutNode = node; }

protected:
    Node               *CreateNode(Node *node);
    Node               *CreateNode(const char *type);
    void                CreateGeometryNode(const char *type,
                                           bool emissiveDefaultColor = false);
    void                CreateGeometryNode(Node *node,
                                           bool emissiveDefaultColor = false);
    void                CreateScript();
    void                CreateElevationGrid();
    void                CreateGeoElevationGrid();
    void                CreateViewpoint();
    void                CreateGeoViewpoint();
    void                CreateNurbsPlane();
    void                CreateNurbsCurve();
    void                CreateNurbsCurve2D();
    void                CreateSuperExtrusion(int numPoints = -1);
    void                CreateSuperRevolver();
    Node               *InsertNode(const char *type);
    Node               *InsertNode(int fieldType, const char *type);
    void                InsertAudioClip();
    void                InsertImageTexture();
    void                InsertMultiTexture();
    void                InsertMultiTextureCoordinate();
    void                InsertMultiTextureTransform();
    void                InsertMultiGeneratedTextureCoordinate();
    void                InsertTextureCoordinate(bool generator);
    void                InsertNormal();
    void                InsertInline(bool withLoadControl = false);
    void                InsertMovieTexture();
    void                InsertNewNurbsNode(Node *nurbsNode, Node* parent);
    void                InsertRigidBody();
    void                InsertVrmlScene();
    void                InsertCubeTexture();
    void                InsertHAnimJoint();
    void                InsertHAnimSegment();
    void                InsertHAnimSite();
    void                CreateVirtualAcoustics();
    void                InsertVirtualSoundSource();

    void                InsertNodeByName();

    Node               *getInsertNode(Node *node);

    void                ToggleCreateAtZero(int index);
    void                ToggleFullScreen();
    void                ToggleView(int direction, SceneView *view, int id,
                                   const char *name);
    void                ShowView(int direction, SceneView *view, int id,
                                 const char *name);
    void                UpdateNumbers4Kids(void);
    STOOLBAR            LoadToolbar(ToolbarWindow *tbWin, int id, int count,
                                    const int *buttons, int menuid,
                                    const char *prefName);
    STOOLBAR            LoadToolbar(ToolbarWindow *tbWin, int id, int count,
                                    const NodeButton *buttons, int menuid,
                                    const char *prefName);
    void                ToggleToolbar(ToolbarWindow *tbWin, STOOLBAR toolbar,
                                      int id, const char *name);
    void                ToggleStatusbar();

    void                setTMode(TMode mode);
    void                setTDimension(TDimension dimension);
    void                setT2axes(T2axes axes);

    void                setColorCircleIcon();
    int                 getMouseMode() {return(_mouseMode);}
    bool                getMouseNavigationMode() 
                           {return(_navigation_mouse_active);}
    bool                getInputDeviceNavigationMode() 
                           {return(_navigation_input_device_active);}
    void                OnEditCut();
    void                OnEditCopy();
    void                OnEditCopyBranchToRoot();
    void                OnEditPaste();
    void                OnEditDelete();
    void                OnEditFind();
    void                OnEditFindAgain();
    void                Play();
    void                Stop();
    void                Record();
    char               *getFileSelectorText(void);
    bool                OpenFileCheck(const char *path);
    void                ImportFileCheck(const char *path, Node *node, 
                                        int field);
    void                RefreshRecentFileMenu();
    void                RefreshProtoMenu();
    void                RefreshHelpSelection();
    void                UpdateTitle();
    void                updateColorCircle(void);
    void                OnHelpOverview();
    void                OnHelpOverviewCatt();
    void                OnHelpSelection();
    void                OnHelpCoverSelection();

    void                EditScript(Node* oldnode);
    void                EditObject();
    void                EditUrl();
    void                CreateAnimation(void);
    void                CreateInteraction(void);
    void                setXSymetricNurbsIcon();

    void                moveSibling(int command);
    void                moveSiblingUp()    { moveSibling(MOVE_SIBLING_UP); }
    void                moveSiblingDown()  { moveSibling(MOVE_SIBLING_DOWN); }
    void                moveSiblingFirst() { moveSibling(MOVE_SIBLING_FIRST); }
    void                moveSiblingLast()  { moveSibling(MOVE_SIBLING_LAST); }

    void                moveBranchToParent(void);
    void                moveBranchToTransformSelection(void);
    void                moveBranchTo(const char* nodeName, 
                                     const char* fieldName);
    void                moveBranchTo(Node* node, int field, Node* current);
    void                moveBranchToInline();
    void                doWithBranch(DoWithNodeCallback callback, void *data);
    void                doWithBranchUpdate(DoWithNodeCallback callback, 
                                           void *data);
    void                branchConvertToTriangleSetUpdate(void);
    void                branchConvertToIndexedFaceSetUpdate(void);
    void                branchConvertToIndexedTriangleSetUpdate(void);

    void                setBranchFlipSide(void);
    void                setBranchConvex(void);
    void                setBranchSolid(void);
    void                setBranchTwoSided(void);
    void                setBranchCreaseAngle(void);
    void                setBranchTransparency(void);
    void                setBranchShininess(void);
    void                createBranchImageTexture(void);
    void                createBranchAppearance(void);
    void                createBranchMaterial(void);
    void                removeBranchNode(void);
    void                branchFieldPipe(void);
    void                branchBuildRigidBodyCollection();
    void                removeIllegalNodes();
    Node               *getTransformForCenter();
    void                centerToMid();
    void                centerToMax(int index);
    void                centerToMin(int index);
    void                InsertArray(void);
    void                flip(int index);
    void                swap(int fromTo);
    void                flatten(int index, bool zero = false);
    void                setDefault();
    void                triangulate(void);
    void                optimizeSet(void);
    void                degreeElevate(int degree);
    void                uDegreeElevate(int degree);
    void                vDegreeElevate(int degree);
    void                toNurbs();
    void                toNurbsCurve();
    void                toSuperRevolver();
    void                toSuperExtrusion();
    void                toExtrusion();
    void                toIndexedFaceSet();
    void                toIndexedTriangleSet();
    void                toTriangleSet();
    void                toIndexedLineSet();
    void                toPointSet();
    void                toPositionInterpolator();
    void                toOrientationInterpolator(Direction direction);
    void                timeShift();
    void                toggleXrayRendering();
    void                countPolygons();
    void                countPolygons4catt();
    void                setPathAllURLs();
    void                clearStatusText();
    void                testInMenu();
    void                swapDiffuseEmissiveShape(NodeShape *shape,
                                                 ColorConversion conversion);
    void                CreateStarFish(int numberArms);
    void                CreateFlower(int numberLeaves);
    void                CreateTube(bool hornFlag = false);
    void                CreateTorus(void);
    void                CreateHalfSphere(void);
    void                CreateShell(void);
    void                CreateUfo(void);
    void                CreateInsectRear(int segments);
    void                CreateHeart(void);
    void                CreateSpindle(void);
    void                CreateMushroom(bool sulcate);
    void                showDiffuseColorCircle(void);
    void                showEmissiveColorCircle(void);
    void                showSpecularColorCircle(void);
    void                changeEnableAnimation(void);
    void                changeDisableAnimation(void);
    void                changeAnimationTime(void);
    void                changeTransparency(void);
    void                changeShininess(void);
    void                changeImageRepeat(void);
    void                createOneText(void);
    void                changeOneText(void);
    void                linearUknot(void);
    void                linearVknot(void);
    bool                isEditorInUse(bool errormessage = false);
    void                fieldPipe(Node *node, int field, const char *command);
    void                pipeField(void);
    int                 considerIdRanges(int id);
    void                HandleScale(void);
    void                HandleSize(void);
    void                HandleEpsilon(void);
    void                setName(int id);
    void                createText(int id);
    void                toogleMaterialName(int id);
#ifdef HAVE_SAND
    void OnSANDExport(void);
#endif

protected:
    SWND                _parentWindow;
    SMENU               _menu;
    StatusBar          *_statusBar;
    ToolbarWindow      *_toolbarWindow;
    ToolbarWindow      *_toolbarWindow2;
    PanedWindow        *_innerPane;
    PanedWindow        *_outerPane;
    SceneView          *_treeView;
    SceneView          *_S3DView;
    SceneView          *_fieldView;
    bool                _showNumbers4Kids;
    SceneView          *_graphView;
    ChannelView        *_channelView;
    STOOLBAR            _standardToolbar;
    STOOLBAR            _nodeToolbar1;
    bool                _nodeToolbar1Enabled;
    STOOLBAR            _nodeToolbar2;
    bool                _nodeToolbar2Enabled;
    STOOLBAR            _nodeToolbar3;
    bool                _nodeToolbar3Enabled;
    STOOLBAR            _nodeToolbarVRML200x;
    bool                _nodeToolbarVRML200xEnabled;
    STOOLBAR            _nodeToolbarX3DComponents1;
    bool                _nodeToolbarX3DComponents1Enabled;
    STOOLBAR            _nodeToolbarX3DComponents2;
    bool                _nodeToolbarX3DComponents2Enabled;
    STOOLBAR            _nodeToolbarX3DComponents3;
    bool                _nodeToolbarX3DComponents3Enabled;
    STOOLBAR            _nodeToolbarX3DComponents4;
    bool                _nodeToolbarX3DComponents4Enabled;
    STOOLBAR            _nodeToolbarCover;
    bool                _nodeToolbarCoverEnabled;
    STOOLBAR            _nodeToolbarKambi;
    bool                _nodeToolbarKambiEnabled;
    STOOLBAR            _nodeToolbarScripted;
    bool                _nodeToolbarScriptedEnabled;
    STOOLBAR            _vcrToolbar;
    STIMER              _timer;
    bool                _fullScreen_enabled;
    SceneView          *_colorCircle;    
    FieldUpdate        *_colorCircleHint;
    bool                _colorCircle_active;
    bool                _colorCircle_enabled;
    bool                _objectEdit_enabled;
    bool                _urlEdit_enabled;
    bool                _navigation_mouse_active;
    bool                _navigation_input_device_active;
    int                 _mouseMode;
    bool                _xOnly;
    bool                _yOnly;
    bool                _zOnly;
    SWND                _fieldCanvas;
    Array<ProtoMenuItem>_protoMenu;
    ScriptEdit         *_scriptEdit;
    bool                _scriptEditorInUse;
    ObjectEdit         *_shaderEdit;
    bool                _textEditorInUse;
    ImageTextureEdit   *_imageTextureEdit;
    PixelTextureEdit   *_pixelTextureEdit;
    bool                _imageEditorInUse;
    MovieTextureEdit   *_movieEdit;
    bool                _movieEditorInUse;
    AudioClipEdit      *_soundEdit;
    bool                _soundEditorInUse;
    int                 _selectedField;
    char                _statusText[256];
    MyString            _searchText;
    Node               *_vrmlCutNode;
    MyString            _fieldPipeFilterNode;
    MyString            _fieldPipeFilterField;
    MyString            _fieldPipeCommand;
#ifdef HAVE_SAND
    ExportNebula        _nebulaExporter;
#endif
};

#endif /* _MAIN_WINDOW_H */
