#include "SM_DemoScriptPCH.h"
#include "SM_DemoEffect.h"
#include "DemoFXResources.h"




SM_DemoEffect* EffectInstances=0;

namespace SM_DEData
{
  CVideoBuffer  VideoBuffer;  
}

SM_DemoEffect::SM_DemoEffect(char const* pcName)
{

  m_iLayer=0;

  // Linkamos a lista
  m_pNextEffect=EffectInstances;    
  EffectInstances=this;

  // asignamos nombre
  m_pcInstanceName=pcName;
  m_pParent=0;
}

SM_DemoEffect::~SM_DemoEffect()
{
  Shutdown();
}

int SM_DemoEffect::Init(const char* pcCommand)
{
  return (0);
}

int SM_DemoEffect::Shutdown()
{
  return (0);
}

int SM_DemoEffect::Reload(const char* pcCommand)
{
  Shutdown();
  return Init(pcCommand);
}

int SM_DemoEffect::Start(float fTime)
{
  return (0);
}

int SM_DemoEffect::Stop()
{
  return (0);
}

int SM_DemoEffect::Run(float fTime)
{

  return (1);
}

void SM_DemoEffect::RunPreStartFrame  (float fTime)
{
}

void SM_DemoEffect::RunPreRender      (float fTime)
{
}

void SM_DemoEffect::RunPostRender     (float fTime)
{
}

void SM_DemoEffect::RunPostEndFrame   (float fTime)
{
} 

void SM_DemoEffect::RunPreLayer(int iLayer, float fTime)
{
}

void SM_DemoEffect::RunPostLayer(int iLayer, float fTime)
{
}
  
void SM_DemoEffect::SetLayer(int iLayer)
{
    m_iLayer=iLayer;
}

int SM_DemoEffect::Command(float fTime, const char* pcCommand)
{
  char* pcCopy=new char[strlen(pcCommand)+1];
  strcpy(pcCopy, pcCommand);

  char* pcToken=strtok(pcCopy, " \t");

  if (strcmp(pcToken, "LAYER")==0)
  {

    pcToken=strtok(0, " \t");

    SetLayer(atoi(pcToken));
    
    if (m_iLayer<0 || m_iLayer>=MAX_LAYERS)
    {
      assert(!"Invalid layer. Must be between 0 and 7");
    }
  }
   
  delete[] pcCopy; pcCopy=0;

  return (0);
}

int SM_DemoEffect::SetParent(SM_DemoEffect* pDemoEffect)
{
  m_pParent=pDemoEffect;
  return 0;
}

bool SM_DemoEffect::DoPrecache        ()
{
  return true;
}

HMODULE SM_DemoEffect::m_Resources = 0;
  
int SM_DemoEffect::InitResources()
{
  assert(!SM_DemoEffect::m_Resources);

  SM_DemoEffect::m_Resources = LoadLibrary("SM_Resources.dll");
  if (!SM_DemoEffect::m_Resources)
  {
    return -1;
  }

  return 0;
}

int SM_DemoEffect::ShutdownResources()
{
  assert(SM_DemoEffect::m_Resources);
  FreeLibrary(SM_DemoEffect::m_Resources);
  SM_DemoEffect::m_Resources = 0;

  return 0;
}


static SM_DemoEffect::Helper  LoadHelp[] =
{
  {"DEFAULT 1", "default load 1"},
  {"DEFAULT 2", "default load 2"},
  {"DEFAULT 3", "default load 3"},
  {"DEFAULT 4", "default load 4"},
  {"DEFAULT 5", "default load 5"},
  {"DEFAULT 6", "default load 6"},
  {"DEFAULT 7", "default load 7"},
  {"DEFAULT 8", "default load 8"},
  {"DEFAULT 9", "default load 9"},
  {"DEFAULT 10", "default load 10"},
  {"DEFAULT 11", "default load 11"},
};

static SM_DemoEffect::Helper CommandsHelp[] =
{
  {"DEFAULT 1", "default command 1"},
  {"DEFAULT 2", "default command 2"},
  {"DEFAULT 3", "default command 3"},
  {"DEFAULT 4", "default command 4"},
  {"DEFAULT 5", "default command 5"},
  {"DEFAULT 6", "default command 6"},
  {"DEFAULT 7", "default command 7"},
  {"DEFAULT 8", "default command 8"},
  {"DEFAULT 9", "default command 9"},
  {"DEFAULT 10", "default command 10"},
  {"DEFAULT 11", "default command 11"},
};


int   SM_DemoEffect::LoadArgumentsHelp     (Helper*& pHelpers)
{
  pHelpers = LoadHelp;
  return (sizeof(LoadHelp)/sizeof(Helper));
}

int   SM_DemoEffect::CommandArgumentsHelp  (Helper*& pHelpers)
{
  pHelpers = CommandsHelp;
  return (sizeof(CommandsHelp)/sizeof(Helper));
}

BOOL CALLBACK  SM_DemoEffect::NewCommandDlgProc   ( HWND _hdlg, UINT _uMsg, WPARAM _wparam, LPARAM _lparam)
{
  static NewCommandDlgProcData* pData = 0;
  switch (_uMsg)
  {
    case WM_INITDIALOG :
    {
      pData = (NewCommandDlgProcData*) _lparam;
      
      
      int iHelpers = pData->m_pEffect->CommandArgumentsHelp(pData->m_pHelpers);
  
      for (int i = 0 ; i < iHelpers ; i++)
      {
        ListBox_InsertString(GetDlgItem( _hdlg, IDC_AVAILABLECOMMANDS), i, pData->m_pHelpers[i].pcCommand);
      }

      Edit_SetText(GetDlgItem( _hdlg, IDC_COMMANDARGUMENTS), pData->m_pcCommandArguments);

      RECT r;
      GetClientRect(_hdlg, &r);

      SetWindowPos(_hdlg,0,
          (GetSystemMetrics(SM_CXSCREEN)-r.right)/2,
          (GetSystemMetrics(SM_CYSCREEN)-r.bottom)/2,r.right,r.bottom, SWP_NOSIZE | SWP_NOOWNERZORDER);
     
      return TRUE;
    }        
    case WM_COMMAND :
      switch ( LOWORD(_wparam) )
      {
      case IDOK:
        {
          HWND hedit = GetDlgItem( _hdlg, IDC_COMMANDARGUMENTS);
          Edit_GetText(hedit, pData->m_pcCommandArguments, pData->m_iMaxLength-1);
          pData->m_pcCommandArguments[pData->m_iMaxLength-1]='\0';
          EndDialog( _hdlg, IDOK );
          break;
        }
      case IDCANCEL :
        EndDialog( _hdlg, IDCANCEL );
        break;
      case IDC_AVAILABLECOMMANDS:
        {
          switch (HIWORD(_wparam))
          {
          case LBN_SELCHANGE:
            int iItem = ListBox_GetCurSel(GetDlgItem( _hdlg, IDC_AVAILABLECOMMANDS));
            Edit_SetText(GetDlgItem( _hdlg, IDC_COMMANDARGUMENTS), pData->m_pHelpers[iItem].pcCommand);            
            Edit_SetText(GetDlgItem( _hdlg, IDC_COMMANDHELP), pData->m_pHelpers[iItem].pcHelp);
            break;
          }
          
        }
      }
      break;
  }

  return FALSE;
}


int SM_DemoEffect::NewCommand(char* pcCommand, int iSize)
{
  NewCommandDlgProcData Data;

  Data.m_pcCommandArguments = pcCommand;
  Data.m_iMaxLength         = iSize;
  Data.m_pEffect            = this;
  if (DialogBoxParam(	
      SM_DemoEffect::m_Resources,
      MAKEINTRESOURCE(IDD_COMMANDARGUMENTS),
      0, 
      (DLGPROC)NewCommandDlgProc,
      (LPARAM)&Data) != IDOK)
  {
    return -1;
  }

  return 0;  
}
  

BOOL CALLBACK  SM_DemoEffect::NewEffectDlgProc   ( HWND _hdlg, UINT _uMsg, WPARAM _wparam, LPARAM _lparam)
{
  static NewEffectDlgProcData* pData = 0;
  switch (_uMsg)
  {
    case WM_INITDIALOG :
    {
      pData = (NewEffectDlgProcData*) _lparam;

      int iHelpers = pData->m_pEffect->LoadArgumentsHelp(pData->m_pHelpers);
  
      for (int i = 0 ; i < iHelpers ; i++)
      {
        ListBox_InsertString(GetDlgItem( _hdlg, IDC_AVAILABLELOADS), i, pData->m_pHelpers[i].pcCommand);
      }

      Edit_SetText(GetDlgItem( _hdlg, IDC_LOADARGUMENTS), pData->m_pcLoadArguments);

      RECT r;
      GetClientRect(_hdlg, &r);

      SetWindowPos(_hdlg,0,
          (GetSystemMetrics(SM_CXSCREEN)-r.right)/2,
          (GetSystemMetrics(SM_CYSCREEN)-r.bottom)/2,r.right,r.bottom, SWP_NOSIZE | SWP_NOOWNERZORDER);
     
      
      
      return TRUE;
    }        
    case WM_COMMAND :
      switch ( LOWORD(_wparam) )
      {
      case IDOK:
        {
          HWND hedit = GetDlgItem( _hdlg, IDC_LOADARGUMENTS);
          Edit_GetText(hedit, pData->m_pcLoadArguments, pData->m_iMaxLength-1);
          pData->m_pcLoadArguments[pData->m_iMaxLength-1]='\0';
          EndDialog( _hdlg, IDOK );
          break;
        }
      case IDCANCEL :
        EndDialog( _hdlg, IDCANCEL );
        break;
      case IDC_AVAILABLELOADS:
        {
          switch (HIWORD(_wparam))
          {
          case LBN_SELCHANGE:
            int iItem = ListBox_GetCurSel(GetDlgItem( _hdlg, IDC_AVAILABLELOADS));
            Edit_SetText(GetDlgItem( _hdlg, IDC_LOADARGUMENTS), pData->m_pHelpers[iItem].pcCommand);            
            Edit_SetText(GetDlgItem( _hdlg, IDC_LOADHELP), pData->m_pHelpers[iItem].pcHelp);
            break;
          }          
        }
      }
      break;
  }

  return FALSE;
}

int SM_DemoEffect::NewEffect(char* pcLoadArguments, int iSize)
{
  NewEffectDlgProcData Data;

  Data.m_pcLoadArguments = pcLoadArguments;
  Data.m_iMaxLength      = iSize;
  Data.m_pEffect         = this;
  if (DialogBoxParam(	
      SM_DemoEffect::m_Resources,
      MAKEINTRESOURCE(IDD_LOADARGUMENTS),
      0, 
      (DLGPROC)NewEffectDlgProc,
      (LPARAM)&Data) != IDOK)
  {
    return -1;
  }
  return 0;
}


SM_DemoEffect* GetEffect(const char* pcName)
{
  SM_DemoEffect* pEffect;

  for (pEffect=EffectInstances ; pEffect ; pEffect=pEffect->m_pNextEffect)
  {
    if (strcmp(pEffect->m_pcInstanceName, pcName)==0)
    {
      return (pEffect);
    }
  }

  return (0);
}



int SM_DemoEffect::m_iRandCount=0;

void* SM_DEData::CVideoBuffer::GetSurfacePointer()
{
  return (m_pVideo);
}

void* SM_DEData::CVideoBuffer::GetSurfacePointer(unsigned x, unsigned y)
{
  return ((void*)((char*)m_pVideo+
			x*(m_uBPP>>3)+
			y*(m_uByteStride)));
}



SM_DEData::CVideoBuffer VideoBuffer;
