#include "xheaders.h"

#include XControlEvent_i
#include XDragEvent_i
#include XWindow_i
#include XPoint_i
#include XDragItem_i
#include XMouseEvent_i
#include XContainerEvent_i
#include XKeyboardEvent_i
#include XContainerObject_i
#include XContainerDragEvent_i
#include XContainerEditEvent_i
#include XString_i
#include XContainerColumn_i
#include XItemDrawEvent_i

#include <stdlib.h>

#ifdef OOL_FOR_OS2_X86
    #define GBN_BUTTONUP      0x0524
    #define GBN_BUTTONDOWN    0x0525
#endif


/*DOC
CLASS XContainerEvent
FUNCTION GetObject
REMARKS returns the object which posted the event
Parameters:    -
Returns:       XContainerObject * the Object (can be NULL)
*/
XContainerObject * XContainerEvent :: GetObject( void )
{
   if( core )
     {
        RECORDCORE * pr = (RECORDCORE *) ((PBYTE) core + sizeof(RECORDCORE));
        XContainerObject * obj;
        memcpy(&obj, pr, 4);
        return obj;
     }
   else
      return NULL;
}


XContainerEvent :: XContainerEvent (XWindow * w, MPARAM mp1, MPARAM mp2): XControlEvent( SHORT2FROMMP(mp1) )
{
  core = NULL;

  if(mp1)
     {
        windowID = SHORT1FROMMP(mp1);
        window = w->GetWindow(windowID);
     }

  if(!window)
     return;

  eventID = SHORT2FROMMP(mp1);

  switch( eventID )
    {
       case CN_EMPHASIS:
          {
             PNOTIFYRECORDEMPHASIS e = (PNOTIFYRECORDEMPHASIS) mp2;
             core = e->pRecord;
          }
          break;
       case CN_ENTER:
          {
             NOTIFYRECORDENTER * enter = (NOTIFYRECORDENTER*) mp2;
             core = enter->pRecord;
          }
          break;
       case CN_INITDRAG:
          {
             CNRDRAGINIT * dragInit = (CNRDRAGINIT*) mp2;
             core = dragInit->pRecord;
          }
          break;
       default:
          core = (PRECORDCORE) mp2;
    }
}


XContainerEditEvent :: XContainerEditEvent( XWindow * w, MPARAM mp1, MPARAM mp2):XContainerEvent(w, mp1, mp2)
{
   cnEdit = (CNREDITDATA*) mp2;
   core = cnEdit->pRecord;
}


void XContainerEditEvent :: QueryText( XString * s)
{
   memcpy( s->GetBuffer( cnEdit->cbText + 1), cnEdit->ppszText, cnEdit->cbText + 1);
   s->ReleaseBuffer();
}


XContainerColumn * XContainerEditEvent :: QueryColumn(void)
{
   return (XContainerColumn*) cnEdit->pFieldInfo->pUserData;
}


XContainerDragEvent :: XContainerDragEvent(XWindow * w, MPARAM mp1, MPARAM mp2):XContainerEvent(w, mp1, mp2)
{
   if(mp2 )
      {
         CNRDRAGINFO * info =(CNRDRAGINFO*) mp2;
         core = info->pRecord;
         dragInfo = info->pDragInfo;
      }
}


void XContainerDragEvent :: SetAcceptMode( SHORT mode )
{
   accept = mode;
}


void XContainerDragEvent :: SetOperation( SHORT op)
{
   operation = op;
}


SHORT XContainerDragEvent ::QueryDragItemCount( void )
{
   if(!(dragInfo))
      return -1;
   else
      return dragInfo->cditem;
}


OOL_WINDOWHANDLE XContainerDragEvent :: QuerySourceWindow( void )
{
   if(!(dragInfo))
      return 0;
   else
      return dragInfo->hwndSource;
}


SHORT XContainerDragEvent :: QueryDragOperation(void)
{
  return dragInfo->usOperation;
}


BOOL XContainerDragEvent :: QueryDropPos( XPoint * p)
{
   if((!(dragInfo)) || eventID != DRG_DROP)
      return FALSE;
   p->SetX( dragInfo->xDrop);
   p->SetY( dragInfo->yDrop);
   return TRUE;
}


XContainerDragEvent ::  ~XContainerDragEvent()
{
  if(dragInfo) DrgFreeDraginfo(dragInfo);
  dragInfo = NULL;
}


BOOL XContainerDragEvent :: QueryDragItem( XDragItem * itm, SHORT index)
{
   if(!(dragInfo))
      return FALSE;
   if( index > dragInfo->cditem)
      return FALSE;

   DRAGITEM * pItem = DrgQueryDragitemPtr( dragInfo, index);
   itm->item = pItem;
   return TRUE;
}


XControlEvent :: XControlEvent( XWindow * w, void * mp1, void * mp2)
{
  windowID = SHORT1FROMMP(mp1);
  window = w->GetWindow( windowID );
  if(!window)
     return;

  char str[5];
  WinQueryClassName( window->GetHandle(), 5, (PCH) str);
  str[0] = ' ';
  SHORT type = atol(str);

  switch( type )
     {
        case 2:   //Combo
           switch (SHORT2FROMMP(mp1))
              {
                 case CBN_LBSELECT:
                    eventID = WIN_SELECTED;
                    break;
                 case CBN_ENTER:
                    eventID = WIN_ENTER;
                    break;
                 case CBN_LBSCROLL:
                    eventID = WIN_VSCROLL;
                    break;
                 case CBN_EFSCROLL:
                    eventID = WIN_HSCROLL;
                    break;
                 case CBN_SHOWLIST:
                    eventID = WIN_SHOWLIST;
                    break;
                 case CBN_EFCHANGE:
                    eventID = WIN_CHANGED;
                    break;
              }
              break;
        case 3:   //Button
           if( SHORT2FROMMP(mp1) == BN_CLICKED)
               eventID = WIN_CHANGED;
           break;
        case 6:   //Entry
           switch (SHORT2FROMMP(mp1))
              {
                 case EN_CHANGE:
                    eventID = WIN_CHANGED;
                    break;
                 case EN_SCROLL:
                    eventID = WIN_HSCROLL;
                    break;
                 case EN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case EN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
               }
               break;
        case 7:   //Listbox
           switch (SHORT2FROMMP(mp1))
              {
                 case LN_SELECT:
                    eventID = WIN_SELECTED;
                    break;
                 case LN_ENTER:
                    eventID = WIN_ENTER;
                    break;
                 case LN_SCROLL:
                    eventID = WIN_HSCROLL;
                    break;
                 case LN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case LN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
              }
              break;
        case 10:  //MLE
           switch (SHORT2FROMMP(mp1))
              {
                 case MLN_CHANGE:
                    eventID = WIN_CHANGED;
                    break;
                 case MLN_VSCROLL:
                    eventID = WIN_VSCROLL;
                    break;
                 case MLN_HSCROLL:
                    eventID = WIN_HSCROLL;
                    break;
                 case MLN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case MLN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
              }
              break;
        case 32:  //SpinButton
           switch (SHORT2FROMMP(mp1))
              {
                 case SPBN_CHANGE:
                    eventID = WIN_CHANGED;
                    break;
                 case SPBN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case SPBN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
                 case SPBN_UPARROW:
                    eventID = WIN_UPARROW;
                    break;
                 case SPBN_DOWNARROW:
                    eventID = WIN_DOWNARROW;
                    break;
                 case SPBN_ENDSPIN:
                    eventID = WIN_ENDTRACK;
                    break;
              }
              break;
        case 37:
           switch (SHORT2FROMMP(mp1))
              {
                 case CN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
                 case CN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
              }
              break;
        case 38: //Slider
           switch (SHORT2FROMMP(mp1))
              {
                 case SLN_CHANGE:
                    eventID = WIN_CHANGED;
                    break;
                 case SLN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case SLN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
                 case SLN_SLIDERTRACK:
                    eventID = WIN_TRACK;
                    break;
              }
              break;
        case 39: //Valueset
           switch (SHORT2FROMMP(mp1))
              {
                 case VN_SELECT:
                    eventID = WIN_SELECTED;
                    break;
                 case VN_ENTER:
                    eventID = WIN_ENTER;
                    break;
                 case VN_SETFOCUS:
                    eventID = WIN_SETFOCUS;
                    break;
                 case VN_KILLFOCUS:
                    eventID = WIN_KILLFOCUS;
                    break;
              }
              break;
        case 64: //GraphicButton
           switch (SHORT2FROMMP(mp1))
              {
                 case GBN_BUTTONDOWN:
                 case GBN_BUTTONUP:
                    eventID = WIN_CHANGED;
                    break;
              }
              break;
        case 65:  //CircularSlider
           switch (SHORT2FROMMP(mp1))
              {
                 case CSN_CHANGED:
                    eventID = WIN_CHANGED;
                    break;
                 case CSN_SETFOCUS:
                    {
                       BOOL e = (BOOL) mp2;
                       if( e )
                          eventID = WIN_SETFOCUS;
                       else
                          eventID = WIN_KILLFOCUS;
                    }
                    break;
                 case CSN_TRACKING:
                    eventID = WIN_TRACK;
                    break;
              }
      }
   window->DoControl( this );
}


/*DOC
CLASS XDragEvent
FUNCTION SetAcceptMode
REMARKS set the operation supported by the application which receives
the drag-event
Parameters:    SHORT accept              the opperation, possible values are
                                             DRG_DROP       accept the items
                                             DRG_NODROP     dont accept the items in this case
                                             DRG_NEVERDROP  never accept the items
Returns:       -
*/
void XDragEvent :: SetAcceptMode( SHORT mode )
{
   accept = mode;
}


/*DOC
CLASS XDragEvent
FUNCTION SetOperation
REMARKS set the operation supported by the application which generates
the drag-event
Parameters:    SHORT operation           the opperation, possible values are
                                             DRG_COPY   copy the items
                                             DRG_MOVE   move the items
                                             DRG_LINK   link the items

Returns:       -
*/
void XDragEvent :: SetOperation( SHORT op)
{
   operation = op;
}


XDragEvent :: ~XDragEvent()
{
  if(dragInfo) DrgFreeDraginfo(dragInfo);
  dragInfo = NULL;
}


XDragEvent :: XDragEvent( LONG event, void * v)
{
   switch( event )
     {
        case DM_DROP:
           eventID = DRG_DROPPED;
           break;
        case DM_DRAGOVER:
           eventID = DRG_DRAGOVER;
           break;
        case DM_DISCARDOBJECT:
           eventID = DRG_DISCARDOBJECT;
           break;
        case DM_ENDCONVERSATION:
           eventID = DRG_ENDCONVERSATION;
           break;
     }

   dragInfo = NULL;
   DRAGINFO * info = (DRAGINFO*) v;
   if(DrgAccessDraginfo(info))
      dragInfo = info;
   accept = DRG_NODROP;
   operation = 0;
}


/*DOC
CLASS XDragEvent
FUNCTION QueryDragItemCount
REMARKS Return the count of drag-items of this dragevent

Parameters:    -
Returns:       SHORT                     count of items
*/
SHORT XDragEvent ::QueryDragItemCount( void )
{
   if(!(dragInfo))
      return -1;
   else
      return dragInfo->cditem;
}


SHORT XDragEvent :: QueryDragOperation(void)
{
  return dragInfo->usOperation;
}

/*DOC
CLASS XDragEvent
FUNCTION QuerySourceWindow
REMARKS Query the system-define handle of the window where the objects
were dropped.

Parameters:    -
Retunrs:       OOL_WINDOWHANDLE          The system-defined window handle.
*/
OOL_WINDOWHANDLE XDragEvent :: QuerySourceWindow( void )
{
   if(!(dragInfo))
      return 0;
   else
      return dragInfo->hwndSource;
}


/*DOC
CLASS XDragEvent
FUNCTION QueryDropPos
REMARKS Query the position where the objects were dropped

Parameters:    XPoint * position         buffer which will get the position
Retuns:        -
*/
BOOL XDragEvent :: QueryDropPos( XPoint * p)
{
   if((!(dragInfo)) || eventID != DRG_DROP)
      return FALSE;
   p->SetX( dragInfo->xDrop);
   p->SetY( dragInfo->yDrop);
   return TRUE;
}


/*DOC
CLASS XDragEvent
FUNCTION QueryDragItem
REMARKS Query a dragitem.

Parameters:    XDragItem * buffer        buffer which will get the item-information
               SHORT index               zero-based index of item to query
Retuns:        -
*/
BOOL XDragEvent :: QueryDragItem( XDragItem * itm, SHORT index)
{
   if(!(dragInfo))
      return FALSE;
   if( index > dragInfo->cditem)
      return FALSE;

   DRAGITEM * pItem = DrgQueryDragitemPtr( dragInfo, index);
   itm->item = pItem;
   return TRUE;
}


XMouseEvent :: XMouseEvent( LONG e, void * v1, void * v2)
{
   switch(e)
      {
        case WM_BUTTON1DOWN:
          eventID = MOU_BTN1DOWN;
          break;
        case WM_BUTTON1DBLCLK:
          eventID = MOU_BTN1DBLCLICK;
          break;
        case WM_BUTTON1CLICK:
          eventID = MOU_BTN1CLICK;
          break;
        case WM_BUTTON1UP:
          eventID = MOU_BTN1UP;
          break;
        case WM_BUTTON2DOWN:
          eventID = MOU_BTN2DOWN;
          break;
        case WM_BUTTON2DBLCLK:
          eventID = MOU_BTN2DBLCLICK;
          break;
        case WM_BUTTON2CLICK:
          eventID = MOU_BTN2CLICK;
          break;
        case WM_BUTTON2UP:
          eventID = MOU_BTN2UP;
          break;
        case WM_BUTTON3DOWN:
          eventID = MOU_BTN3DOWN;
          break;
        case WM_BUTTON3DBLCLK:
          eventID = MOU_BTN3DBLCLICK;
          break;
        case WM_BUTTON3CLICK:
          eventID = MOU_BTN3CLICK;
          break;
        case WM_BUTTON3UP:
          eventID = MOU_BTN3UP;
          break;
        default:
          eventID = e;
          break;
      }

   p.SetX( SHORT1FROMMP(v1) );
   p.SetY( SHORT2FROMMP(v1) );

   keyboardState = SHORT2FROMMP((MPARAM) v2);
}


XItemDrawEvent :: XItemDrawEvent( LONG msg , void* mp1, void* mp2)
{
   eventID = msg;
   windowID = SHORT1FROMMP(mp1);
   item = (POWNERITEM) mp2;
}


LONG XItemDrawEvent :: GetWindowID(void)
{
   return windowID;
}


LONG XItemDrawEvent :: GetItemID (void)
{
   return item->idItem;
}


OOL_WINDOWHANDLE XItemDrawEvent :: GetWindowHandle( void )
{
   return item->hwnd;
}

////////////////////////docs only
/*DOC
CLASS XEvent
FUNCTION GetEventID
REMARKS GetEventID return the ID of the event which ocures. Valid
IDïs are specified by the classes derived from XEvent
Parameters:   -
Returns:      ULONG theEventID
*/



/*DOC
CLASS XControlEvent
FUNCTION GetEventID
REMARKS returns a pointer to the window which has send the event

Parameters:  -
Returns:     LONG id                     the id of the event, see XControlEvent.
*/



/*DOC
CLASS XControlEvent
FUNCTION GetWindow
REMARKS returns a pointer to the window which has send the event

Parameters:  -
Returns:     XWindow * thePointer    the pointer of the sending window, if you
                                     know the window type, you can typecast to
                                     the needed class
*/



/*DOC
CLASS XControlEvent
FUNCTION GetWindowID
REMARKS returns the ID of the window which has send the event
Parameters:  -
Returns:     LONG theWindowID        the ID of the sending window
*/


/*DOC
CLASS XMouseEvent
FUNCTION GetEventID
REMARKS returns the ID of the mouse-event. To get a mouse-event you must
register a XMouseHandler!
Parameters:  -
Returns:     LONG theID              the ID of the mouse-event, see XMouseEvent.
*/


/*DOC
CLASS XMouseEvent
FUNCTION GetKeyInfo
REMARKS returns the state of the keyboard
Parameters:  -
Returns:     SHORT keyInfo           information of the keyboard
*/

