#include <GL/glut.h>
#include <string>

#include "CWindow.h"
#include "CActiveWin.h"

CActiveWin* g_Window;



////////////////////////////////////////////////////////////////
//                                                            //
//  Callback functions that will actually be called by GLUT.  //
//                                                            //
////////////////////////////////////////////////////////////////

void Display(void)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetDisplayFunc())();
}

void Reshape(int width, int height)
{
  g_Window->SetWidth(width);
  g_Window->SetHeight(height);

  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetReshapeFunc())(width, height);
}

void Keyboard(unsigned char key, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetKeyboardFunc())(key, x, y);
}

void Mouse(int button, int state, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetMouseFunc())(button, state, x, y);
}

void Motion(int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetMotionFunc())(x, y);
}

void PassiveMotion(int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetPassiveMotionFunc())(x, y);
}

void Entry(int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetEntryFunc())(state);
}

void Visibility(int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetVisibilityFunc())(state);
}

void Idle(void)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetIdleFunc())();
}

void MenuState(int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetMenuStateFunc())(state);
}


#if (GLUT_API_VERSION >= 2)

void Special(int key, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetSpecialFunc())(key, x, y);
}

void SpaceballMotion(int x, int y, int z)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetSpaceballMotionFunc())(x, y, z);
}

void SpaceballRotate(int x, int y, int z)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetSpaceballRotateFunc())(x, y, z);
}

void SpaceballButton(int button, int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetSpaceballButtonFunc())(button, state);
}

void ButtonBox(int button, int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetButtonBoxFunc())(button, state);
}

void Dials(int dial, int value)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetDialsFunc())(dial, value);
}

void TabletMotion(int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetTabletMotionFunc())(x, y);
}

void TabletButton(int button, int state, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetTabletButtonFunc())(button, state, x, y);
}


#if (GLUT_API_VERSION >= 3)

void MenuStatus(int status, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetMenuStatusFunc())(status, x, y);
}

void OverlayDisplay(void)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetOverlayDisplayFunc())();
}


#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)

void WindowStatus(int state)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetWindowStatusFunc())(state);
}

#endif


#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)

void KeyboardUp(unsigned char key, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetKeyboardUpFunc())(key, x, y);
}

void SpecialUp(int key, int x, int y)
{
  CWindow* curwin = g_Window->GetCurrentWin();
  (curwin->*curwin->GetSpecialUpFunc())(key, x, y);
}

#endif
#endif
#endif






#define ACTIVATE(x)       \
if (Code & MYGLUT_##x##)  \
  glut##x##Func(##x##);

void CActiveWin::Activate(unsigned int Code)
{
  ACTIVATE(Display);
  ACTIVATE(Reshape);
  ACTIVATE(Keyboard);
  ACTIVATE(Mouse);
  ACTIVATE(Motion);
  ACTIVATE(PassiveMotion);
  ACTIVATE(Entry);
  ACTIVATE(Visibility);
  ACTIVATE(Idle);
#if (GLUT_API_VERSION >= 2)
  ACTIVATE(MenuState);
  ACTIVATE(Special);
  ACTIVATE(SpaceballMotion);
  ACTIVATE(SpaceballRotate);
  ACTIVATE(SpaceballButton);
  ACTIVATE(ButtonBox);
  ACTIVATE(Dials);
  ACTIVATE(TabletMotion);
  ACTIVATE(TabletButton);
#if (GLUT_API_VERSION >= 3)
  ACTIVATE(MenuStatus);
  ACTIVATE(OverlayDisplay);
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
  ACTIVATE(WindowStatus);
#endif
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
  ACTIVATE(KeyboardUp);
  ACTIVATE(SpecialUp);
#endif
#endif
#endif
}
