/* 
   Copyright 2001-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
**********************************************************************

LSGRIP.C is a container window, like LSCTRL.  However instead of containing
standard windows, it contains toolbars.  When they are docked they will
be inside LSGRIP controls, otherwise inside standard windows.
 
**********************************************************************

*/
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "lsctrl.h"

#define TITLEWIDTH 15
#define EDGEWIDTH 1
#define TITLETOP 4
#define BARLEFT 2
#define BARRIGHT 2
#define BARTOP 0
#define BUTTONCORNER 1
#define BUTTONWIDTH 12

static char *szGripWindClassName = "ladSoftGripWindow" ;
static char *szTBContainerClassName = "ladSoftTBContainerWindow" ;
static char *szBlankWindowClassName = "ladSoftBlankWindow" ;

static HCURSOR mcurs ;

static void DrawBorder(HDC dc, RECT *r1,int vertical)
{
#ifdef XXXXX
   HBRUSH brush = CreateSolidBrush(GetSysColor(COLOR_INACTIVEBORDER)) ;
   RECT r2 ;

   r2 = *r1 ;
   if (vertical)
      r2.right = r2.left + TITLEWIDTH ;
   else
      r2.right = r2.left + EDGEWIDTH ;
   FillRect(dc,&r2,brush) ;

   r2 = *r1 ;
   r2.left = r2.right -EDGEWIDTH ;
   FillRect(dc,&r2,brush) ;

   r2 = *r1 ;
   if (vertical)
      r2.bottom = r2.top + EDGEWIDTH ;
   else
      r2.bottom = r2.top + TITLEWIDTH ;
   FillRect(dc,&r2,brush) ;

   r2 = *r1 ;
   r2.top = r2.bottom - EDGEWIDTH ;
   FillRect(dc,&r2,brush) ;

   DeleteObject(brush) ;
#endif
}
static void DrawTitle(HDC dc, RECT *r, int vertical)
{
   HPEN pen1,pen2,pen3,oldpen ;                       
         pen1 = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DLIGHT)) ;
         pen2 = CreatePen(PS_SOLID, 2, GetSysColor(COLOR_3DHILIGHT)) ;
         pen3 = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)) ;
         if (vertical) {
            r->top = TITLETOP ;
            r->left+=EDGEWIDTH ;
            r->right-=EDGEWIDTH ;
            oldpen = SelectObject(dc,pen1) ;
            SelectObject(dc,pen1) ;
            MoveToEx(dc,r->left + BARLEFT,r->top+BARTOP,0) ;
            LineTo(dc,r->right - BARRIGHT + 1, r->top+BARTOP) ;
            SelectObject(dc,pen2) ;
            MoveToEx(dc,r->left + BARLEFT-1,r->top+BARTOP+1,0) ;
            LineTo(dc,r->right - BARRIGHT , r->top+BARTOP+1) ;
            SelectObject(dc,pen3) ;
            MoveToEx(dc,r->left + BARLEFT,r->top+BARTOP+3,0) ;
            LineTo(dc,r->right - BARRIGHT + 1, r->top+BARTOP+3) ;
            SelectObject(dc,pen2) ;
            MoveToEx(dc,r->left + BARLEFT-1,r->top+BARTOP+5,0) ;
            LineTo(dc,r->right - BARRIGHT, r->top+BARTOP+5) ;
            SelectObject(dc,pen3) ;
            MoveToEx(dc,r->left + BARLEFT,r->top+BARTOP+7,0) ;
            LineTo(dc,r->right - BARRIGHT + 1, r->top+BARTOP+7) ;
         } else {
            r->left = TITLETOP ;
            r->top += EDGEWIDTH ;
            r->bottom-=EDGEWIDTH ;
            oldpen = SelectObject(dc,pen1) ;
            MoveToEx(dc,r->left+BARTOP,r->top+BARRIGHT-1,0) ;
            LineTo(dc,r->left+BARTOP,r->bottom-BARLEFT) ;
            SelectObject(dc,pen2) ;
            MoveToEx(dc,r->left+BARTOP+1,r->top+BARRIGHT,0) ;
            LineTo(dc,r->left+BARTOP+1,r->bottom-BARLEFT+1) ;
            SelectObject(dc,pen3) ;
            MoveToEx(dc,r->left+BARTOP+3,r->top+BARRIGHT-1,0) ;
            LineTo(dc,r->left+BARTOP+3,r->bottom-BARLEFT) ;
            SelectObject(dc,pen2) ;
            MoveToEx(dc,r->left+BARTOP+5,r->top+BARRIGHT,0) ;
            LineTo(dc,r->left+BARTOP+5,r->bottom-BARLEFT + 1) ;
            SelectObject(dc,pen3) ;
            MoveToEx(dc,r->left+BARTOP+7,r->top+BARRIGHT-1,0) ;
            LineTo(dc,r->left+BARTOP+7,r->bottom-BARLEFT) ;
         }                    
         SelectObject(dc, oldpen) ;
         DeleteObject(pen1) ;
         DeleteObject(pen2) ;
         DeleteObject(pen3) ;
}
static LRESULT  CALLBACK _export GripWindWndProc( HWND hwnd, UINT iMessage, WPARAM wParam,
                                                         LPARAM lParam )
{
   RECT r, *pr ;
   PAINTSTRUCT ps ;
   HDC dc ;
   CCW_params *ptr ;
   static int skip ;
   static int dragging,oncursor,sizing ;
   static HCURSOR oldCursor ;
   POINT temppt ;
   int temp ;
   HBRUSH brush ;
   switch(iMessage) {
      case WM_NOTIFY:
         break ;
      case WM_COMMAND:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         break ;
      case WM_LBUTTONDOWN :
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         temppt.x = (long)(short)LOWORD(lParam) ;
         temppt.y = (long)(short)HIWORD(lParam) ;
         if ((ptr->vertical && temppt.y < 17) ||
               (!ptr->vertical && temppt.x < 17))  {
            dmgrStartMoveGrip(ptr,lParam) ;
            oldCursor = SetCursor(mcurs) ;
            SetCapture(hwnd) ;
            dragging = TRUE ;
         }
         break ;
      case WM_LBUTTONUP:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         if (dragging) {
            SetCursor(oldCursor) ;
            oldCursor = 0 ;
         }
         if (dragging)
            ReleaseCapture() ;
         dragging = FALSE ;
         sizing = FALSE ;
         dmgrEndMoveGrip(ptr) ;
         break ;
      case WM_MOUSEMOVE:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         if (dragging) {
            dmgrMoveGrip(ptr, lParam) ;
         }
         break ;
      case WM_PAINT:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         dc = BeginPaint(hwnd, &ps) ;
         GetClientRect(hwnd,&r) ;
         DrawBorder(dc,&r,ptr->vertical) ;
         
         DrawTitle(dc,&r,ptr->vertical) ;
         EndPaint(hwnd, &ps) ;
         break ;
		case WM_CREATE :
         ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CCW_params)) ;
         SetWindowLong(hwnd,0,(DWORD)ptr) ;
         *ptr = *(CCW_params *)(((LPCREATESTRUCT)lParam)->lpCreateParams) ;
         ptr->self = hwnd ;
         ptr->type = LSGRIP ;
         dmgrAddGrip(ptr) ;
         GetClientRect(hwnd,&r) ;
			return 0 ;
		case WM_DESTROY:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         HeapFree(GetProcessHeap(),0,ptr) ;
         break ;
		case WM_CLOSE:

         return 0 ;
      case LCF_SETVERTICAL:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         ptr->vertical = (int) lParam ;
         InvalidateRect(hwnd,0,0) ;
         return 0 ;
      case WM_SIZE :
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         if (ptr->vertical)
            MoveWindow(ptr->u.gp.child,  0, TITLEWIDTH, LOWORD(lParam),HIWORD(lParam),FALSE) ;
         else
            MoveWindow(ptr->u.gp.child,  TITLEWIDTH, 0, LOWORD(lParam),HIWORD(lParam),FALSE) ;
         return 0 ;
	}
   return DefWindowProc(hwnd, iMessage, wParam, lParam) ;
}
LRESULT  CALLBACK _export TBContainerProc( HWND hwnd, UINT iMessage, WPARAM wParam,
                                 LPARAM lParam )
{
   CCW_params *ptr ;
   static int selected, sizingbottom ;
   RECT r, *pr ;
   TC_ITEM tie ;
   NMHDR *h ;
   DRAWITEMSTRUCT *dr ;
   HFONT font ;
   HBITMAP hbmp ;
   HDC hMemDC ;
   HDWP deferstruct ;
   HDC dc ;
   PAINTSTRUCT ps ;
   static int dragging,oncursor,sizing ;
   static HCURSOR oldCursor ;
   POINT temppt ;
   switch(iMessage) {
      case WM_NCHITTEST:
         return HTCLIENT ;
      case WM_SYSCOMMAND:
         if (wParam == SC_CLOSE) {
            PostMessage(hwnd,WM_CLOSE,0,0) ;
         }
         break ;
      case WM_LBUTTONDOWN :
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         temppt.x = (long)(short)LOWORD(lParam) ;
         temppt.y = (long)(short)HIWORD(lParam) ;
         if (temppt.y < GetSystemMetrics(SM_CYCAPTION))  {
            dmgrStartMoveGrip(ptr,lParam) ;
            oldCursor = SetCursor(mcurs) ;
            SetCapture(hwnd) ;
            dragging = TRUE ;
         }
         break ;
      case WM_LBUTTONUP:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         if (dragging) {
            SetCursor(oldCursor) ;
            oldCursor = 0 ;
         }
         if (dragging)
            ReleaseCapture() ;
         dragging = FALSE ;
         sizing = FALSE ;
         dmgrEndMoveGrip(ptr) ;
         break ;
      case WM_MOUSEMOVE:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         if (dragging) {
            dmgrMoveGrip(ptr, lParam) ;
         }
         break ;
		case WM_NOTIFY:
         h = (NMHDR *)lParam ;
			break ;
		case WM_CREATE :
         ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CCW_params)) ;
         SetWindowLong(hwnd,0,(DWORD)ptr) ;
//         *ptr = *(CCW_params *)(((LPMDICREATESTRUCT)lParam)->lParam) ;
         ptr->self = hwnd ;
         ptr->type = LSTBCONT ;
         dmgrAddContainer(ptr) ;
			return 0 ;
      case WM_PAINT:
         dc = BeginPaint(hwnd, &ps) ;
         GetClientRect(hwnd,&r) ;
         EndPaint(hwnd, &ps) ;
         break ;
		case WM_COMMAND:
         break ;
		case WM_DESTROY:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         HeapFree(GetProcessHeap(),0,ptr) ;
         break ;
      case WM_SIZE :
         break;
		case WM_CLOSE:
         return 0 ;
      case WM_MOVE:
         break ;
	}
   return DefMDIChildProc(hwnd, iMessage, wParam, lParam) ;
}
static LRESULT  CALLBACK _export BlankWindowWndProc( HWND hwnd, UINT iMessage, WPARAM wParam,
                                                         LPARAM lParam )
{
   RECT r, *pr ;
   PAINTSTRUCT ps ;
   HDC dc ;
   CCW_params *ptr ;
   static int skip ;
   static int dragging,oncursor,sizing ;
   static RECT moverect ;
   static HCURSOR oldCursor ;
   POINT temppt, movept ;
   int temp ;
   switch(iMessage) {
      case WM_NOTIFY:
         SendMessage(GetParent(hwnd),iMessage,wParam,lParam) ;
         break ;
      case WM_COMMAND:
         SendMessage(GetParent(hwnd),iMessage,wParam,lParam) ;
         break ;
      case WM_PAINT:
         ptr = (CFW_params *)GetWindowLong(hwnd,0) ;
         dc = BeginPaint(hwnd, &ps) ;
         EndPaint(hwnd, &ps) ;         
         break ;
		case WM_CREATE :
         ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(CCW_params)) ;
         SetWindowLong(hwnd,0,(DWORD)ptr) ;
         *ptr = *(CCW_params *)(((LPCREATESTRUCT)lParam)->lpCreateParams) ;
         ptr->self = hwnd ;
         ptr->type = LSBLANK ;
         dmgrAddBlank(hwnd) ;
			return 0 ;
		case WM_DESTROY:
         ptr = (CCW_params *)GetWindowLong(hwnd,0) ;
         HeapFree(GetProcessHeap(),0,ptr) ;
         break ;
		case WM_CLOSE:
         return 0 ;
      case WM_SIZE :
         break ;
      case WM_MOVE :
         break ;
	}
   return DefWindowProc(hwnd, iMessage, wParam, lParam) ;
}

void RegisterGripWindow(HINSTANCE hInstance)
{
		WNDCLASS wc ;
      memset(&wc,0,sizeof(wc)) ;
      wc.style = CS_PARENTDC ;
      wc.lpfnWndProc = &GripWindWndProc ;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = sizeof(LPVOID);
		wc.hInstance = hInstance ;
		wc.hIcon = LoadIcon(0,IDI_APPLICATION) ;
		wc.hCursor = LoadCursor(0,IDC_ARROW) ;
      wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_INACTIVEBORDER)) ;
		wc.lpszMenuName = 0 ;
      wc.lpszClassName = szGripWindClassName ;
		RegisterClass(&wc) ;

      memset(&wc,0,sizeof(wc)) ;
      wc.style = 0;
      wc.lpfnWndProc = &TBContainerProc ;
		wc.cbClsExtra = 0;
      wc.cbWndExtra = 4;
		wc.hInstance = hInstance ;
		wc.hIcon = LoadIcon(0,IDI_APPLICATION) ;
		wc.hCursor = LoadCursor(0,IDC_ARROW) ;
      wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_INACTIVEBORDER)) ;
		wc.lpszMenuName = 0 ;
      wc.lpszClassName = szTBContainerClassName ;
		RegisterClass(&wc) ;

      memset(&wc,0,sizeof(wc)) ;
      wc.style = CS_PARENTDC ;
      wc.lpfnWndProc = &BlankWindowWndProc ;
		wc.cbClsExtra = 0;
      wc.cbWndExtra = sizeof(LPVOID);
		wc.hInstance = hInstance ;
		wc.hIcon = LoadIcon(0,IDI_APPLICATION) ;
      wc.hCursor = 0;
      wc.hbrBackground = CreateSolidBrush(GetSysColor(COLOR_INACTIVEBORDER)) ;
		wc.lpszMenuName = 0 ;
      wc.lpszClassName = szBlankWindowClassName ;
		RegisterClass(&wc) ;

      mcurs = LoadCursor(hInstance,"ID_MOVECUR") ;

}
HWND CreateContainerWindow(HWND parent, RECT *r)
{
   CCW_params p ;
      HWND hwnd ;
   hwnd = CreateMDIWindow(szTBContainerClassName, "",
            WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME,
            r->left,r->top,r->right-r->left,r->bottom-r->top, 
            parent, (HINSTANCE)GetWindowLong(parent,GWL_HINSTANCE), (LPARAM)&p) ;

   return hwnd ;
}
HWND CreateBlankWindow(HWND parent, RECT *r)
{
   CCW_params p ;
   HWND hwnd ;
   hwnd = CreateWindow(szBlankWindowClassName, "",
            WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD | WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME,
            r->left,r->top,r->right-r->left,r->bottom-r->top, 
            parent, (HMENU)0 ,(HINSTANCE)GetWindowLong(parent,GWL_HINSTANCE), &p) ;

   return hwnd ;
}
HWND CreateGripWindow(HWND parent, RECT *r, int vertical)
{
   CCW_params p ;
   HWND hwnd ;
   RECT r1,r2 ;
   p.vertical = vertical ;
   hwnd = CreateWindow(szGripWindClassName, "",
            WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_CHILD,
            r->left,r->top,r->right-r->left,r->bottom-r->top, 
            parent, (HMENU)0 ,(HINSTANCE)GetWindowLong(parent,GWL_HINSTANCE), &p) ;

   return hwnd ;
}