/*------------------------------------------------------------------------------*
 * File Name:ResizeDialog.h														*
 * Creation: CPY 6/12/2003														*
 * Purpose: OriginC Header file for basic dialog functions						*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	DVT 8/1/03 TWO_GAPS_WHEN_BOTTOM_NULL										*
 *	CPY 9/13/03 PLOT_SETUP_PANEL_RESIZE_FROM_INSIDE_GRID						*
 *------------------------------------------------------------------------------*/

#include <Tree_utils.h>

#ifndef _RESIZE_CONTROL_H_
	#include "ResizeControl.h"
#endif //_RESIZE_CONTROL_H_

#define FACTOR_ORIG_TO_MIN  			0.8

enum{ PANEL_ORIENT_NONE, PANEL_ORIENT_VERTICAL, PANEL_ORIENT_HORIZONTAL };

#define MAX_ALLOWED_PANELS				5


class ResizeDialog : public Dialog
{
public:
	ResizeDialog(UINT nDlgID, LPCSTR lpcszDLL) :  Dialog(nDlgID, lpcszDLL)
	{
		m_bRepaintWhenMove = true;
		/// TD 8-26-03 RESIZING
		m_bDoNotHandleOnSize = true;
		m_nNumPanels = 0;
		for(int ii = 0; ii < MAX_ALLOWED_PANELS; ii++)
		{
			m_parrPanels[ii] = NULL;
		}
		/// ----TD 8-26-03 RESIZING
	}
	void SetControlGap(int nEdge) {m_nEdge = nEdge;}
	void AddPanel(ResizeControl* pPanel)
	{
		m_parrPanels[m_nNumPanels++] = pPanel;
	}
	virtual string GetRuntimeClass()
	{
		return "ResizeDialog";
	}
		
protected:
	//---- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
	void SaveDlgHeight() { m_nDlgHight = GetDlgExtent();}

	BOOL OnResize(int nType, int cx, int cy) // return TRUE only if OnSize is enabled
	{
		if(m_bDoNotHandleOnSize)
		{
			//m_nDlgHight = cy;
			return FALSE;
		}
		resizePanelsOnDlgResize(cx, cy);
		return TRUE;
	}
	//---- CPY 9/13/03 PLOT_SETUP_PANEL_RESIZE_FROM_INSIDE_GRID
	// wParam = Panel index, 0 = wks List, 1 = col List, 3 = Plot List for example, this is the panel that we need to increase/decrease its height
	// lParam = LPARAM_RESIZE_CONTROLS_INCREASE, LPARAM_RESIZE_CONTROLS_DECREASE
	//
	BOOL OnIncreaseDecreasePanelSize(uint wParam, uint lParam)
	{
		bool bIncrease = LPARAM_RESIZE_CONTROLS_INCREASE == lParam? true:false;
		int nSizeDiff = 0;
		if(wParam < getNumOfPanels())
		{
			ResizeControl *pKeyPanel = m_parrPanels[wParam];
			if(!bIncrease || isDlgSmallerThenScreen(0, 0.9)) // simply decrease given panel
			{
				nSizeDiff = bIncrease? pKeyPanel->GetHeight() * (-0.75) : pKeyPanel->GetHeight() * 0.45;
				pKeyPanel->SetHeight(pKeyPanel->GetHeight() - nSizeDiff);
				return true;
			}
			// to increase, we will try not to increase the dialog since often there is no space to expand dialog
			// so we will need to grab space from other panels. To do this, we ask each panel how much it can give up
			// by comparing its current height and its GetMinHeight(true), so the extra is what we can add to the current (wParam) panel
			int nDiffs[MAX_ALLOWED_PANELS];
			int ii, ny, nTotal = 0;
			for(ii = 0; ii < getNumOfPanels(); ii++)
			{
				nDiffs[ii] = 0;
				if(wParam == ii)
					continue;
				if(m_parrPanels[ii]->IsVisible())
				{
					int ndiff = m_parrPanels[ii]->GetHeight() - m_parrPanels[ii]->GetMinHeight(true);
					if(ndiff < 0)
						ndiff = 0;
					nTotal += ndiff;
					nDiffs[ii] = ndiff;
				}
			}
			ny = pKeyPanel->GetHeight();
			int nn = pKeyPanel->GetMaxHeight(true);
			if(ny > nn)
				ny = nn;
			nSizeDiff = nTotal;
			if(0 == nSizeDiff || nSizeDiff > 0.4 * ny)
				nSizeDiff = 0.4 * ny;
			double factor = nSizeDiff / (double)nTotal;
			for(ii = 0; ii < getNumOfPanels(); ii++)
			{
				if(wParam == ii)
					continue;
				if(nDiffs[ii] > 0)
					m_parrPanels[ii]->SetHeight(m_parrPanels[ii]->GetHeight() - (0.5 + factor*nDiffs[ii])); 	
			}
			pKeyPanel->SetHeight(pKeyPanel->GetHeight() + nSizeDiff); 	
		}
		return TRUE;
	}
	//---- end PLOT_SETUP_PANEL_RESIZE_FROM_INSIDE_GRID
	int GetTotalHeight(bool bMin = false) // by summing up each panels, assume vertical, need to modify if to support general
	{
		int nTotalHeight = 0;
		bool bAnyVisible = false;
		for(int ii = 0; ii < getNumOfPanels(); ii++)
		{
			if(m_parrPanels[ii]->IsVisible())
			{
				bAnyVisible = true;
				nTotalHeight += m_parrPanels[ii]->GetPanelHeight(bMin) + GetControlGap();
			}
		}
		if(bAnyVisible)
			nTotalHeight -= GetControlGap();
		
		return nTotalHeight;
	}
	int GetTotalWidth(bool bGetMin = false)
	{
		int mx, nx = 0;
		for(int ii = 0; ii < getNumOfPanels(); ii++)
		{
			if(m_parrPanels[ii]->IsVisible())
			{
				mx = m_parrPanels[ii]->GetPanelWidth(true);
				if(GetPanelsOrientation() == PANEL_ORIENT_VERTICAL && mx > nx)
					nx = mx;
				else if(GetPanelsOrientation() == PANEL_ORIENT_HORIZONTAL)
					nx += mx; // + GetControlGap()
			}
		}
		return nx;
	}
	//---- end CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
	bool SetMoveRepaint(bool bRepaint = true)
	{
		bool bOldVal = m_bRepaintWhenMove;
		m_bRepaintWhenMove = bRepaint;
		return bOldVal;
	}
	int GetDlgExtent(bool bVertial = true)
	{
		RECT r1;
		m_wndDlg.GetClientRect(&r1);
		return bVertial? r1.bottom : r1.right;
	}
	int GetControlGap() { return m_nEdge; }

	HWND	GetSafeHwnd()
	{
		return m_wndDlg.GetSafeHwnd();
	}	
	void ShowControls(uint nButtonIDs[], bool bShow = true)
	{
		int ii = 0;
		while(nButtonIDs[ii] > 0)
		{
			Control btn = GetItem(nButtonIDs[ii]);
			if(btn)
				btn.Visible = bShow;
			
			ii++;
		}
	}
	void EnableControls(uint nButtonIDs[], bool bEnable = true)
	{
		int ii = 0;
		while(nButtonIDs[ii] > 0)
		{
			Control btn = GetItem(nButtonIDs[ii]);
			if(btn)
				btn.Enable = bEnable;
			
			ii++;
		}
	}
	void CheckButtons(uint nButtonIDs[], bool bCheck = true)
	{
		int ii = 0;
		while(nButtonIDs[ii] > 0)
		{
			Button btn = GetItem(nButtonIDs[ii]);
			if(btn)
				btn.Check = bCheck;
			
			ii++;
		}
	}
	// use default gap if nGap < 0
	// return the right most x position
	int ArrangControlsTopDown(uint nButtonIDs[], int nx, int ny, int nGap = -1)
	{
		RECT rr, r1;
		rr.left = nx;
		rr.top = ny;
		if(nGap < 0)
			nGap = m_nEdge;
		int ii = 0;
		int nMaxWidth = 0;
		while(nButtonIDs[ii] > 0)
		{
			Control btn = GetItem(nButtonIDs[ii]);
			if(btn && btn.Visible)
			{
				btn.GetWindowRect(&r1);
				rr.bottom = rr.top + RECT_HEIGHT(r1);
				if(nMaxWidth < RECT_WIDTH(r1))
					nMaxWidth = RECT_WIDTH(r1);
				rr.right = rr.left + RECT_WIDTH(r1);
				btn.MoveWindow(&rr, m_bRepaintWhenMove);

				rr.top = rr.bottom + nGap;
			}
			ii++;
		}
		return nx + nMaxWidth;
	}
	// starting from nx, ny as the top-right position, move controls one after another to
	// the left, nGap < 0 will use default gap between controls
	// return the lowest y position
	int ArrangeControlsRightLeft(uint nButtonIDs[], int nx, int ny, int nGap = -1)
	{
		RECT rr, r1;
		if(nGap < 0)
			nGap = m_nEdge;
		rr.right = nx - nGap;
		rr.top = ny;
		int ii = 0;
		int nMaxHeight = 0;
		while(nButtonIDs[ii] > 0)
		{
			Control btn = GetItem(nButtonIDs[ii]);
			if(btn && btn.Visible)
			{
				btn.GetWindowRect(&r1);
				rr.left = rr.right - RECT_WIDTH(r1);
				if(nMaxHeight < RECT_HEIGHT(r1))
					nMaxHeight = RECT_HEIGHT(r1);
				rr.bottom = rr.top + RECT_HEIGHT(r1);
				btn.MoveWindow(&rr, m_bRepaintWhenMove);

				rr.right = rr.left - nGap;
			}
			ii++;
		}
		return ny + nMaxHeight;
	}
	// position nMainID as top-left and move nIDsRight group of controls to the far right and nIDsBottom to the left bottom
	//nIDsRight should be moved only horizontally, while nIDsBottom should be moved only vertically
	//nMainID should be resize right-bottom, while keeping top-left
	//cx is the right most x pixel
	//cy is the bottom y pixel
	bool ResizeMoveControlsRightBottom(int nMainID, uint nRightIDs[], uint nBottomIDs[], int cx, int cy)
	{
		int nRightGroupWidth = getControlGroupExtent(nRightIDs, true);
		int nBottomGroupHeight = getControlGroupExtent(nBottomIDs, false);
		int nRightGroupLeft = cx - m_nEdge - nRightGroupWidth;
		int	nBottomGroupTop = cy - m_nEdge - nBottomGroupHeight;
		RECT r1;
		r1.left = 0;
		if(nRightIDs && !GetControlClientRect(nRightIDs[0], r1))
			return false;
		int nRightGroupOffset = nRightGroupLeft - r1.left;
		r1.top = 0;
		if(nBottomIDs && !GetControlClientRect(nBottomIDs[0], r1))
			return false;
		int nBottomGroupOffset = nBottomGroupTop -  r1.top;
		
		Control cMain;
		if(!GetControlClientRect(nMainID, r1, &cMain))
			return false;
		r1.right = nRightGroupLeft - m_nEdge;
		///	DVT 8/1/03 TWO_GAPS_WHEN_BOTTOM_NULL
		//r1.bottom = nBottomGroupTop - m_nEdge;
		r1.bottom = nBottomGroupTop;
		if(nBottomIDs)
			r1.bottom -= m_nEdge;
		///	end TWO_GAPS_WHEN_BOTTOM_NULL
		cMain.MoveWindow(&r1, m_bRepaintWhenMove);
		if(nRightIDs)
			MoveControls(nRightIDs, nRightGroupOffset, 0);
		if(nBottomIDs)
			MoveControls(nBottomIDs, 0, nBottomGroupOffset);
		return true;
	}
	void MakeSameSize(uint nIDs[], bool bVert = true)
	{
		RECT r0;
		Control btnRef = GetItem(nIDs[0]);
		btnRef.GetWindowRect(&r0);
		int ii = 1;
		while(nIDs[ii] > 0)
		{
			RECT r1;
			Control btn;
			if(GetControlClientRect(nIDs[ii], r1, &btn))
			{
				if(bVert)
					r1.bottom = r1.top + RECT_HEIGHT(r0);
				else
					r1.right = r1.left + RECT_WIDTH(r0);
				
				btn.MoveWindow(&r1, m_bRepaintWhenMove); 
			}
			ii++;
		}
		return;
	}
	bool GetControlClientRect(uint nID, RECT& r1, Control* pCntrl = NULL)
	{
		Control btn;
		if(NULL == pCntrl)
			pCntrl = &btn;
			
		*pCntrl = GetItem(nID);
		if(*pCntrl)
		{
			pCntrl->GetWindowRect(&r1);
			m_wndDlg.ScreenToClient(&r1);
			return true;
		}
		return false;
	}
	void MoveControls(uint nIDs[], int nDx, int nDy)
	{
		int ii = 0;
		while(nIDs[ii] > 0)
		{
			RECT r1;
			Control btn;
			if(GetControlClientRect(nIDs[ii], r1, &btn))
			{
				OffsetRect(&r1, nDx, nDy);
				btn.MoveWindow(&r1, m_bRepaintWhenMove); 
			}
			ii++;
		}
	}
	// return top if bTop = false, return bottom if bTop = true
	int PositionControl(uint nID, int nx, int ny, bool bTop = true, bool bCheckVisible = true)
	{
		Control btn = GetItem(nID);
		int nRet = ny;
		if(btn && (!bCheckVisible || btn.Visible))
		{
			RECT rr, r1;
			btn.GetWindowRect(&r1);
			rr.left = nx;
			if(bTop)
			{
				rr.top = ny, rr.bottom = ny + RECT_HEIGHT(r1);
				nRet = rr.bottom;
			}
			else
			{
				rr.bottom = ny, rr.top = ny - RECT_HEIGHT(r1);
				nRet = rr.top;
			}
			rr.right = nx + RECT_WIDTH(r1);
			btn.MoveWindow(&rr, m_bRepaintWhenMove);
		}
		return nRet;
	}
	// return bottom of control
	int StretchControlWide(uint nID, int nx, int ny, int cx, int nGap = -1)
	{
		Control btn = GetItem(nID);
		if(nGap < 0)
			nGap = m_nEdge;
		if(btn && btn.Visible)
		{
			RECT rr, r1;
			btn.GetWindowRect(&r1);
			rr.left = nx;
			rr.top = ny;
			rr.right = cx - nGap;
			rr.bottom = ny + RECT_HEIGHT(r1);
			btn.MoveWindow(&rr, m_bRepaintWhenMove);
			ny = rr.bottom;
		}
		return ny;
	}
	// return right of control
	
	/// ---- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
	BOOL OnMinMaxInfo(int &nMinTrackX, int &nMinTrackY)
	{
		nMinTrackY = GetTotalHeight(true);
		nMinTrackX = GetTotalWidth(true);
		return TRUE;
	}
	virtual BYTE GetPanelsOrientation()
	{
		return PANEL_ORIENT_NONE;
	}
	void DisableOnSize(bool bDisable = true)
	{
		m_bDoNotHandleOnSize = bDisable;
	}	
	int StretchControlHeight(uint nID, int nx, int ny, int cy, int nGap = -1)
	{
		Control btn = GetItem(nID);
		if(nGap < 0)
			nGap = m_nEdge;
		if(btn && btn.Visible)
		{
			RECT rr, r1;
			btn.GetWindowRect(&r1);
			rr.left = nx;
			rr.top = ny;
			rr.right = nx + RECT_WIDTH(r1);
			rr.bottom = cy - nGap;
			btn.MoveWindow(&rr, m_bRepaintWhenMove);
			nx = rr.right;
		}
		return nx;
	}
	int StretchControlLeftRight(uint nIDLeft, int nIDRight, int nx, int ny, int cx, int nGap = -1)
	{
		Control btnLeft = GetItem(nIDLeft);
		Control btnRight = GetItem(nIDRight);
		if(nGap < 0)
			nGap = m_nEdge;

		RECT rr,r1;
		int ncxReduction = 0, ny1 = 0;
		if(btnRight && btnRight.Visible)
		{
			btnRight.GetWindowRect(&r1);
			ncxReduction = RECT_WIDTH(r1);
			rr.right = cx - nGap;
			rr.left = rr.right - RECT_WIDTH(r1);
			rr.top = ny;
			rr.bottom = ny + RECT_HEIGHT(r1);
			btnRight.MoveWindow(&rr, m_bRepaintWhenMove);
			ny1 = rr.bottom;
		}
		cx -= ncxReduction;	
			
		if(btnLeft && btnLeft.Visible)
		{
			btnLeft.GetWindowRect(&r1);
			rr.left = nx;
			rr.top = ny;
			rr.right = cx - nGap;
			rr.bottom = ny + RECT_HEIGHT(r1);
			btnLeft.MoveWindow(&rr, m_bRepaintWhenMove);
			ny = rr.bottom;
		}
		return ny > ny1? ny:ny1;
	}
		
	// return the gap between controls that might be used by caller
	// for repositioning of other controls
	// bRight = true for arrange along the right edge, = false will arrange along bottom
	int ArrangeMainItemAndControls(uint nButtonIDs[], uint nMainItemID, bool bRight = true, int cx = 0, int cy = 0)
	{		
		RECT r1, r2;
		m_wndDlg.GetClientRect(&r1);
		if(0==cx)
			cx = RECT_WIDTH(r1);
		if(0==cy)
			cy = RECT_HEIGHT(r1);
		
		Button btn1 = GetItem(nButtonIDs[0]);
		btn1.GetWindowRect(&r1);
		int nBtnWidth = r1.right - r1.left;
		int nBtnHeight= r1.bottom - r1.top;
		m_wndDlg.ScreenToClient(&r1);
		int nEdge = m_nEdge;
		
		Control cMainItem = GetItem(nMainItemID);
		cMainItem.GetWindowRect(&r1);
		m_wndDlg.ScreenToClient(&r1);
		if(bRight)
		{
			r1.bottom = cy - nEdge;
			r1.right = cx - nBtnWidth - 2*nEdge;
		}
		else
		{
			r1.right = cx - nEdge;
			r1.bottom = cy - nBtnHeight - 2*nEdge;
		}
		
		cMainItem.MoveWindow(&r1, m_bRepaintWhenMove);
		
		int ii = 0;
		if(bRight)
		{
			r2.left = r1.right + nEdge;
			r2.top = nEdge;
			r2.right = r2.left + nBtnWidth;
			r2.bottom = r2.top + nBtnHeight;
		}
		else
		{
			r2.top = r1.bottom + nEdge;;
			r2.right = cx - nEdge;
			r2.left = r2.right - nBtnWidth;
			r2.bottom = cy - nEdge;
		}
		
		while(nButtonIDs[ii] > 0)
		{
			Control btn = GetItem(nButtonIDs[ii]);
			if(btn && btn.Visible)
			{
				btn.GetWindowRect(&r1);
				if(bRight)
				{
					r2.bottom = r2.top + RECT_HEIGHT(r1);
					btn.MoveWindow(&r2, m_bRepaintWhenMove);
					r2.top = r2.bottom + nEdge;
				}
				else
				{
					r2.left = r2.right - RECT_WIDTH(r1);
					btn.MoveWindow(&r2, m_bRepaintWhenMove);
					r2.right = r2.left - nEdge;
				}
			}
			ii++;
		}
		return nEdge;
	}
	void ResizeDlgToBottomOfControl(int nID)
	{
		RECT r1, rtDlg;
		m_wndDlg.GetWindowRect(&rtDlg);
		m_wndDlg.ScreenToClient(&rtDlg);
		Control cc = GetItem(nID);
		cc.GetWindowRect(&r1);
		m_wndDlg.ScreenToClient(&r1);
		rtDlg.bottom = r1.bottom + r1.left; // assume item is next to edge so can use left as gap to bottom
		m_wndDlg.ClientToScreen(&rtDlg);	
		m_wndDlg.MoveWindow(&rtDlg);
	}
	//nRefID to be used to measure the gap between controls, m_nEdge
	BOOL OnInitDialog(int nRefID = 0)
	{
		m_wndDlg = GetWindow();
		m_nEdge = GetSystemMetrics(SM_CXSIZEFRAME);
		if(nRefID)
		{
			RECT r1;
			if(GetControlClientRect(nRefID, r1))
				m_nEdge = r1.left;
		}
		SaveDlgHeight();//--- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
		return TRUE;
	}
	void UpdateWindow(bool bInvalidate = true)
	{
		if(bInvalidate)
			InvalidateRect(GetSafeHwnd(), NULL, TRUE);
		UpdateWindow(GetSafeHwnd());
	}
private:
	// x y factor, ignore if = 0
	// otherwise compare with screen after using factor as ratio
	bool isDlgSmallerThenScreen(double xFactor, double yFactor)
	{
		bool bXSmaller = xFactor == 0 || xFactor * GetSystemMetrics(SM_CXSCREEN) > GetDlgExtent(false) ? true:false;
		bool bYSmaller = yFactor == 0 || yFactor * GetSystemMetrics(SM_CYSCREEN) > GetDlgExtent(true) ? true:false;
		return bXSmaller && bYSmaller ? true:false;
	}
	/////////// checkbox and save/restore
	void rememberCheckBoxes(LPCSTR lpcszDlgName, int nID1, int nID2 = 0, int nID3 = 0, int nID4 = 0, int nID5 = 0, int nID6 = 0, int nID7 = 0, int nID8 = 0)
	{
		m_strRegSectionCheckBoxesName = lpcszDlgName;
		m_vnCheckBoxIDs.SetSize(0);
		m_vnCheckBoxIDs.Add(nID1);
		if(nID2)
		{
			m_vnCheckBoxIDs.Add(nID2);
			if(nID3)
			{
				m_vnCheckBoxIDs.Add(nID3);
				if(nID4)
				{
					m_vnCheckBoxIDs.Add(nID4);
					if(nID5)
					{
						m_vnCheckBoxIDs.Add(nID5);
						if(nID6)
						{
							m_vnCheckBoxIDs.Add(nID6);
							if(nID7)
							{
								m_vnCheckBoxIDs.Add(nID7);
								if(nID8)
									m_vnCheckBoxIDs.Add(nID8);
							}
						}
					}
				}
						
			}
		}
	}
	// width and height of a group of controls
	// based on [0] item
	int getControlGroupExtent(uint nIDs[], bool bWidth)
	{
		if(NULL == nIDs)
			return 0;
		
		int nCntrlID = nIDs[0];
		if(nCntrlID)
		{
			Control cntrl = GetItem(nCntrlID);
			if(cntrl)
			{
				RECT rect;
				cntrl.GetWindowRect(&rect);
				if(bWidth)
					return RECT_WIDTH(rect);
				else
					return RECT_HEIGHT(rect);
			}
		}
		return 0;
	}
	//---- CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
	int getNumOfPanels()
	{
		return m_nNumPanels;
	}
	bool resizePanelsOnDlgResize(int cx, int cy)
	{
		if(m_bDoNotHandleOnSize)
			return false;

		BYTE bOrient = GetPanelsOrientation();
		int  nExpand = 0;
		if(bOrient == PANEL_ORIENT_VERTICAL)
			nExpand = cy - m_nDlgHight;
		else
		{
			return false; // later, other orientation
		}
		if(0 == nExpand)
			return true;
		int  nDenom = 0;
		int nSizeDiff[MAX_ALLOWED_PANELS];
		int	nOldHeight[MAX_ALLOWED_PANELS];
		for(int ii = 0; ii < getNumOfPanels(); ii++)
		{
			nSizeDiff[ii] = m_parrPanels[ii]->IsResize(nExpand > 0?true:false)? 1:0;
			nOldHeight[ii] = m_parrPanels[ii]->GetHeight();
			if(nSizeDiff[ii])
				nDenom += nOldHeight[ii];
		}
		if(nDenom <= 0)
			return false; // nothing to do
		double dDenom = nDenom;
		for(ii = 0; ii < getNumOfPanels(); ii++)
		{
			if(nSizeDiff[ii])
				nSizeDiff[ii] = nExpand * nOldHeight[ii]/dDenom;
		} 
		for(ii = 0; ii < getNumOfPanels(); ii++)
		{
			if(nSizeDiff[ii])
			{
				if(PANEL_ORIENT_VERTICAL == bOrient)
					m_parrPanels[ii]->SetHeight(nOldHeight[ii] + nSizeDiff[ii]); 
				else
				{
					// later, other orientation
				}
			}
		}
		return true;
	}
	//---- end CPY 9/6/03 v7.5686 RESIZEING_CLEAN_UP
protected:
	void LoadCheckBoxSettings(LPCSTR lpcszDlgName, int nID1, int nID2 = 0, int nID3 = 0, int nID4 = 0, int nID5 = 0, int nID6 = 0, int nID7 = 0, int nID8 = 0)
	{
		rememberCheckBoxes(lpcszDlgName, nID1, nID2, nID3, nID4, nID5, nID6, nID7, nID8);
		
		if(m_vnCheckBoxIDs.GetSize() > 0 && !m_strRegSectionCheckBoxesName.IsEmpty())
		{
			vector<byte> vbCheckSettings;
			if(load_default_checkboxes(m_strRegSectionCheckBoxesName, vbCheckSettings))
			{
				bool bCheck;
				for(int ii = 0; ii < m_vnCheckBoxIDs.GetSize(); ii++)
				{
					if(ii < vbCheckSettings.GetSize())
						bCheck = vbCheckSettings[ii];
					else
						bCheck = false;
					
					Button btnCheck = m_wndDlg.GetDlgItem(m_vnCheckBoxIDs[ii]);
					if(btnCheck)
						btnCheck.Check = bCheck;
				}
			}
		}
	}
	void SaveSizeOfPanels()
	{
		for(int ii = 0; ii < getNumOfPanels(); ii++)
		{
			string strClassName 	= m_parrPanels[ii]->GetRuntimeClass();
			SaveSetting(strClassName, m_parrPanels[ii]->GetHeight());
		}
	}
	void LoadSizeOfPanels()
	{
		for(int ii = 0; ii < getNumOfPanels(); ii++)
		{
			string strClassName 	= m_parrPanels[ii]->GetRuntimeClass();
			int nDefaultSize 	= m_parrPanels[ii]->GetHeight(true);
				
			m_parrPanels[ii]->SetHeight(LoadSetting(strClassName, nDefaultSize));
		}
		
		m_bDoNotHandleOnSize = false;// OK to allow OnSize handling now
	}
	void SaveCheckBoxSettings()
	{
		if(m_vnCheckBoxIDs.GetSize() > 0 && !m_strRegSectionCheckBoxesName.IsEmpty())
		{
			vector<byte> vbCheckSettings;
			bool bCheck = false;
			for(int ii = 0; ii < m_vnCheckBoxIDs.GetSize(); ii++)
			{
				Button btnCheck = m_wndDlg.GetDlgItem(m_vnCheckBoxIDs[ii]);
				if(btnCheck)
					bCheck = btnCheck.Check;
				else
					bCheck = false;
				vbCheckSettings.Add(bCheck);
			}
			save_default_checkboxes(m_strRegSectionCheckBoxesName, vbCheckSettings);
		}
	}
	// if called after LoadCheckBoxSettings, can skip lpcszDlgName
	DWORD LoadSetting(LPCSTR lpcszValName, DWORD dwDefault = 0, LPCSTR lpcszDlgName = NULL)
	{
		string strSecName = lpcszValName;
		if(strSecName.IsEmpty())
			strSecName = m_strRegSectionCheckBoxesName;
		
		DWORD dwVal = dwDefault;
		if(dlg_load_registry(strSecName, lpcszValName, dwVal))
			return dwVal;
		
		return dwDefault;
	}
	void SaveSetting(LPCSTR lpcszValName, DWORD dwVal, LPCSTR lpcszDlgName = NULL)
	{
		string strSecName = lpcszValName;
		if(strSecName.IsEmpty())
			strSecName = m_strRegSectionCheckBoxesName;
		
		dlg_save_to_registry(strSecName, lpcszValName, dwVal);
	}
private:
	int				m_nEdge;
	vector<uint>	m_vnCheckBoxIDs; // connect to registry
	string			m_strRegSectionCheckBoxesName;// for saving and reading bits
	bool			m_bRepaintWhenMove;
	/// ---- TD 8-26-03 RESIZING
	bool	m_bDoNotHandleOnSize;	
	int		m_nDlgHight;
	int		m_nNumPanels;
	ResizeControl *m_parrPanels[MAX_ALLOWED_PANELS];	/// ---- TD 8-26-03 RESIZING
	/// ----
protected:
	Window	m_wndDlg;
	
};

