#ifndef WORKZONE

#define WORKZONE

#include "SM_Window.h"
#include "MBStaticList.h"
#include "Structures.h"
#include "SM_DemoScript.h"

#define ROWHEIGHT  20
#define BARHEIGHT (ROWHEIGHT/2-1)
#define TITLEWIDTH 139

class SM_DemoEffect;

using namespace SM_DemoScript;
struct GUILoadedEffect;

DEFINE_EVGUID(EV_WORKSHEETUPDATE, 0xEA713C19, 0xA3FA, 0x43B2, 0x9B, 0xF7, 0xA4, 0xB1, 0x10, 0x5D, 0x7C, 0x43);

class WorksheetUpdateEvent : public Event
{
public:
  WorksheetUpdateEvent()
  {
    m_pGUID = (EVGUID*) &EV_WORKSHEETUPDATE;
  }
};

DEFINE_EVGUID(EV_WORKSHEETMARKEVENT, 0xC6A5600E, 0x32FF, 0x4748, 0xAD, 0x36, 0x1D, 0x2D, 0xCE, 0x08, 0x27, 0x66);
class WorksheetMarkEvent : public Event
{
  public:
  WorksheetMarkEvent(char* pcText)
  {
    m_pGUID = (EVGUID*) &EV_WORKSHEETMARKEVENT;
    m_pcText = pcText;
  }  

  char* m_pcText;
};

DEFINE_EVGUID(EV_WORKSHEETMODIFIEDEVENT, 0x0F37AA9E4, 0xD9B1, 0x48A9, 0xB1, 0x28, 0x83, 0x4B, 0xFE, 0xDC, 0x0D, 0xA3);
class WorksheetModifiedEvent : public Event
{
  public:
  WorksheetModifiedEvent()
  {
    m_pGUID = (EVGUID*) &EV_WORKSHEETMODIFIEDEVENT;    
  }    
};


class WorksheetWindow : public Window
{
public:
                  WorksheetWindow         ();
                  ~WorksheetWindow        ();
  int             Init                    (Window* pParent , MBStaticList<GUILoadedEffect*>* pslEntryList);
                  
  int             Shutdown                ();
  int             ProcessMessage          (const UINT message, const WPARAM wParam, const LPARAM lParam);    
                  
                  
  void                SetView                 (const DemoIDEView* pDemoIDEView, bool bForceRedraw);
  const DemoIDEView*  GetView                 ();
  void                Paint                   ();
  void                DoPaintPlaying          ();
  int                 UpdateWorksheet         ();
                  
  void                InsertEffect            ();
  void                DeleteEffect            (int iEffect);
  void                ReloadEffect            (int iEffect);
  void                LayerEffect             (int iEffect, int iLayer);
  void                InsertRange             (int iEffect);    
  void                InsertCommand           (int iEffect, int iDeleteOld = -1);
  void                DeleteItem              (int iEffect, int iCommand);
  void                SetActive               (bool bActive);
  void                CopyCommand             (int iEffect, int iCommand);
  void                PasteCommand            ();
                  
protected:        
  int                 InsertCommand           (GUILoadedEffect* pEffect, TCommand::eCommand eType, const char* pcArgs, int iTick);
  void                ResetWidgetList         ();
  void                ShutdownWidgetList      ();
  void                UpdateWidgetTick        (int iWidget, int iTick);
                  
  void                UpdateScrollBar         ();
  void                PaintBar                (HDC hdc, int y, int iStart, int iEnd, 
                                                                HRGN* pBeginRegion,
                                                                HRGN* pEndRegion,
                                                                HRGN* pBarRegion);
  void                PaintCommand            (HDC hdc, int x, int y, HRGN* pCommand);
  void                PaintLimit              (HDC hdc, int x, int y, HRGN* pLimit);
  void                PaintEntry              (HDC hdc, int iEntry, int y);
  void                PaintInactive           (HDC hdc, RECT* pRect);
  void                PaintPlaying            (HDC hdc, int iTick, int h);
  void                PaintCue                (HDC hdc, int iTick, int h, HBRUSH hBrush);
  void                PaintBPM                (HDC hdc, int h);

  bool                IsRangeLimit            (int iEffect, int iCommand);
  void                Reset                   ();


  int             PixelToTick             (int x);
  int             TickToPixel             (int iTick);

  int             GetWidgetFromCoord      (int x, int y, int iMask);    
  
  struct    InsertEffectDlgProcData
  {
    WorksheetWindow* m_pWorksheetWindow;
    SM_DemoEffect*   m_pEffect;
  };

  static  BOOL CALLBACK InsertEffectDlgProc( HWND _hdlg, UINT _uMsg, WPARAM _wparam, LPARAM _lparam);
  
  
  struct sWidget
  {
    enum eWidgetType
    {
      E_COMMAND = 1,
      E_EFFECT  = 2,
      E_RANGE   = 4,
    };

    bool operator==(const sWidget& Widget)
    {
      return (eType == Widget.eType &&
              iGUIEffect == Widget.iGUIEffect &&
              iCommand == Widget.iCommand);
    }

    eWidgetType   eType;
    int           iGUIEffect;
    int           iCommand;
    HRGN          hRegion;
  };
  
  MBStaticList<GUILoadedEffect*>*   m_pslEntryList;
  MBStaticList<sWidget>             m_slWidgets;
  int                               m_iEntryOffset;
  int                               m_iPageSize;
  DemoIDEView                       m_DemoIDEView;
  int                               m_iCurrentEffect;
  sWidget                           m_CurrentWidget;
  int                               m_iCurrentX;
  int                               m_iCurrentTick;
  bool                              m_bActive;
  bool                              m_bDrag;  
  bool                              m_bDragEffect;   

  struct CopyPasteBuffer
  {
    bool  m_bSomething;
    int   iEffect;
    char  pcCommand[1024];
  };

  CopyPasteBuffer                   m_CopyPasteBuffer;

  // GDI Objects
  HBRUSH hBrushEven;
  HBRUSH hBrushOdd;   
  HBRUSH hBrushBlack; 
  HBRUSH hBrushWhite; 
  HBRUSH hBrushGreen; 
  HBRUSH hBrushBPM;
  HBRUSH hBrushHalfRed;
  HBRUSH hBrushGrey;  
  HFONT  hfont;       
  HBRUSH hBrushRed;   
  HBRUSH hLimitFill;
  HPEN   hLimitOutline; 
  HBRUSH hBrushYellow;
  HPEN   hPenHalfYellow;  
};


#endif