#include "xheaders.h"

#include XToolBar_i
#include XFrameWindow_i
#include XRect_i
#include XFrame_i
#include XColor_i
#include XGraphicDevice_i
#include XLine_i
#include XControlEvent_i

#include "stdlib.h"


/*DOC
CLASS XToolBar
FUNCTION Draw
GROUP display
REMARKS redraw the toolbar
*/
void XToolBar :: Draw( void )
{
   if( graph)
      graph->Draw();
}


void XToolBar :: DoCommand( LONG com)
{
   frame->DoCommand( com );
}


void XToolBar :: DoSize( void )
{
  XRect r;
  GetSize( &r );

  cx = r.GetWight();
  line2->SetWight( cx-1);
  XPoint p( cx-1, 0);
  line3->Move( &p );
  line4->SetWight( cx-1);
}


/*DOC
CLASS XToolBar
FUNCTION GetBackgroundColor
GROUP display
REMARKS returns the background color
Parameters: XColor * colorBuffer         buffer which will get the color
Returns:    -
*/
void XToolBar :: GetBackgroundColor( XColor * col)
{
  col->SetGreen( 205);
  col->SetRed( 205 );
  col->SetBlue( 205 );
}


/*DOC
CLASS XToolBar
FUNCTION RemoveWindow
GROUP adding/removing windows
REMARKS Removes a window attached to the toolbar
Parameters: XWindow * theWindow          window to remove
            BOOL redraw                  recalculate the position of other
                                         attached windows

Returns:    BOOL                         success
*/
BOOL XToolBar :: RemoveWindow ( XWindow * w, BOOL redraw )
{
  SHORT i, j;
  XRect or;

  for( i=0; i < clients; i++)
     {
        if( clientWin[i] == w )
           {
              EnableWindowUpdate( FALSE);
              clientWin[i]->GetSize( &or );
              clientWin[i]->Hide();
              for(j=i; j < clients-1; j ++)
                 {
                    clientWin[j] = clientWin[j+1];
                    xOffset[j] = xOffset[j+1];
                    yOffset[j] = yOffset[j+1];
                    if(redraw)
                       {
                         XRect r;
                         clientWin[j]->GetSize( &r );
                         r.SetX( r.GetX() - or.GetWight());
                         clientWin[j]->SetSize( &r );
                       }
                 }
              clients-=1;
              clientWin = (XWindow**) realloc( clientWin, clients*sizeof(XWindow*));
              yOffset = (LONG*) realloc(yOffset, clients*sizeof(LONG));
              xOffset = (LONG*) realloc(xOffset, clients*sizeof(LONG));
              EnableWindowUpdate();
              return TRUE;
           }
     }
  return FALSE;
}

/*DOC
CLASS XToolBar
FUNCTION AddWindow
GROUP adding/removing windows
REMARKS Attach a window to the toolbar
Parameters: XWindow * theWindow          window to add
            BOOL newGroup                with this window a new group starts
            BOOL adjustSize              recalculate the hight of the toolbar
                                         depending on the dimensions of theWindow
            XWindow * insertBehind       insert theWindow behind this window
            LONG xOffset                 x-offset of the window
            LONG yOffset                 yx-offset of the window (usefull on Combos)
Returns:    BOOL                         success
*/
void XToolBar :: AddWindow( XWindow * w, BOOL newGroup, BOOL adjustSize, XWindow * insertBehind, LONG x, LONG y)
{
   XRect r;
   LONG xo = borderSize;
   SHORT ins = clients;

   EnableWindowUpdate( FALSE );

   clients+=1;
   clientWin = (XWindow**) realloc( clientWin, clients*sizeof(XWindow*));
   yOffset = (LONG*) realloc(yOffset, clients * sizeof(LONG));
   xOffset = (LONG*) realloc(xOffset, clients * sizeof(LONG));

   if(clients>1)
      {
         if( insertBehind )
            {
               SHORT i, j;
               for(i=0; i < clients; i++)
                  {
                     if( clientWin[i] == insertBehind)
                        {
                           ins = i+1;
                           clientWin[i]->GetSize( &r );
                           SHORT xDiff = r.GetX() + r.GetWight() + x;
                           if( newGroup )
                              xDiff += spacing;
                           xo = xDiff;
                           XRect r2;
                           w->GetSize( &r2 );
                           xDiff = r2.GetWight();
                           if(newGroup)
                              xDiff+=spacing;
                           for(j=clients-1; j > i+1; j--)
                              {
                                clientWin[j] = clientWin[j-1];
                                xOffset[j] = xOffset[j-1];
                                yOffset[j] = yOffset[j-1];
                                clientWin[j]->GetSize( &r2);
                                r2.SetX( r2.GetX() + xDiff);
                                clientWin[j]->SetSize( &r2);
                              }
                           goto mark1;
                        }
                   }
            }
         else
            {
                clientWin[ins-1]->GetSize(&r);
                xo = r.GetX() + r.GetWight();
                if( newGroup)
                   xo+= spacing;
            }
       }
mark1:
   clientWin[ins] = w;
   yOffset[ins] = y;
   xOffset[ins] = x;

   if( adjustSize)
      {
         XRect rec;
         w->GetSize( &rec);
         if( rec.GetHight() > cy - 2 * borderSize )
           {
              cy = rec.GetHight() + 2 * borderSize;
              SetHight( cy );
              GetSize( &rec );
              rec.SetHight( cy);
              SetSize( &rec );
              ReSize();
          }
      }

   w->GetSize( &r);
   r.SetX( xo + x);
   r.SetY( cy - borderSize- r.GetHight() + y );
   w->SetSize( &r );

   EnableWindowUpdate();
}


/*DOC
CLASS XToolBar
FUNCTION ReSize
GROUP sizing
REMARKS The positions of the attached windows are recalculated
Parameters: -
Returns:    -
*/
void XToolBar :: ReSize( void )
{
  int i;
  XRect r;

  for(i=0; i < clients; i++)
    {
       clientWin[i]->GetSize( &r);
       r.SetY( cy - r.GetHight() - borderSize + yOffset[i] );
       clientWin[i]->SetSize( &r);
    }
}


/*DOC
CLASS XToolBar
FUNCTION XToolBar
GROUP constructors/destructors
REMARKS creates a toolbar
Parameters: XFrameWindow * parent        framewindow wich gets the toolbar
            ULONG style                  the style of the toolbar, possible values are:
                                            TB_TOP      toolbar is on the top of framwindow
                                            TB_BOTTOM   toolbar is on the bottom of framwindow
                                         default is TB_TOP
            USHORT ySize                 hight of the toolbar in pixels, default is 20
            USHORT groupSpace            size between window-groups in pixels, default is 15
Returns:    -
*/
XToolBar :: XToolBar( XFrameWindow * fr, ULONG sty, USHORT ySize, USHORT groupSpace): XFrameControl ( fr, sty )
{
   graph = new XGraphicDevice( this );
   XColor col( COL_PALEGRAY);
   graph->SetBackgroundColor( &col);
   spacing = groupSpace;
   frame = fr;
   borderSize = 5;
   clients=0;
   clientWin = NULL;
   yOffset = xOffset = NULL;

   XColor colWhite( COL_WHITE );
   XPoint p1(0,0), p2(0, cy-2);
   line1 = new XLine( graph, &p1, &p2);
   line1->SetColor( &colWhite );
   p1.SetX( cx - 1);
   p1.SetY( cy - 2);
   line2 = new XLine( graph, &p2, &p1);
   line2->SetColor( &colWhite );
   p2.SetY(0);
   p2.SetX(cx-1);
   line3 = new XLine( graph, &p2, &p1);
   XColor colGray( COL_DARKGRAY );
   line3->SetColor( &colGray);
   p1.SetX(0);
   p1.SetY(0);
   line4 = new XLine( graph, &p1, &p2);
   line4->SetColor( &colGray );
   cy = 0;
   SetHight( ySize );
}


/*DOC
CLASS XToolBar
FUNCTION SetBorderSize
GROUP sizing
REMARKS set the size between the border of the toolbar and the attached windows
Parameters: USHORT borderSize            size of border in pixels
Returns:    -
*/
void XToolBar :: SetBorderSize( USHORT border)
{ borderSize = border;}


/*DOC
CLASS XToolBar
FUNCTION Hide
GROUP display
REMARKS Hides the toolbar
Parameters: -
Returns:    -
*/
void XToolBar :: Hide ( void )
{
   WinShowWindow( winhandle, FALSE );
   SetHight( 0);
}


/*DOC
CLASS XToolBar
FUNCTION Show
GROUP display
REMARKS Shows the toolbar
Parameters: -
Returns:    -
*/
void XToolBar :: Show( void )
{
   WinShowWindow( winhandle, TRUE );
   SetHight( cy );
}


/*DOC
CLASS XToolBar
FUNCTION SetHight
GROUP sizing
REMARKS Set the hight of the toolbar
Parameters: USHORT ySize                 the new hight in pixels
Returns:    -
*/
BOOL XToolBar :: SetHight( USHORT y)
{
   SHORT oldHight = cy;
   SWP swp[200];

   if( IsVisible() )
      cy = y;

   line1->SetHight( y-2);
   XPoint p( 0, y-2);
   line2->Move( &p );
   p.SetX( cx-1);
   p.SetY( 0 );
   line3->Move( &p );
   line3->SetHight( y-2 );

   if( frame->frameWin )
      {
         SWP swp2;
         WinQueryWindowPos( frame->winhandle, &swp2);
         WinSetWindowPos( frame->winhandle, HWND_TOP, 0, 0, swp2.cx, swp2.cy - y, SWP_SIZE | SWP_SHOW |SWP_ZORDER);

         SHORT res = SHORT1FROMMR( WinSendMsg( frame->frameWin->winhandle, WM_QUERYFRAMECTLCOUNT, 0, 0));

         WinSendMsg( frame->frameWin->winhandle, WM_FORMATFRAME, MPFROMP(swp), 0); //hier attention

         SHORT i;
         for(i=0; i < res; i++)
            {
              if(swp[i].hwnd != 0)
                 WinSetWindowPos( swp[i].hwnd, swp[i].hwndInsertBehind, swp[i].x, swp[i].y, swp[i].cx, swp[i].cy, swp[i].fl);
            }

         if( frame->clientWindow == NULL)
            WinInvalidateRegion( frame->winhandle, NULLHANDLE, TRUE);

         return TRUE;
      }
   else
      return FALSE;
}


/*DOC
CLASS XToolBar
FUNCTION ~XToolBar
GROUP constructors/destructors
REMARKS Destructor, evere attached window is destroyed and the destructors of the
windows are called.
Parameters: -
Returns:    -
*/
XToolBar :: ~XToolBar()
{
   WinDestroyWindow( winhandle);
   free( clientWin);
   free( yOffset );
   free( xOffset );
   delete graph;
}

