#include "stdafx.h"
#include "InitFormEx.h"
#include "ProgressBar.h"
#include "StatusBarPanel.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern CBkEndUI * pBkEndUI;

IMPLEMENT_DYNCREATE(CStatusBarPanel,CBLContext);

class CObjID CStatusBarPanel::ObjID;

struct CStatusBarPanel::paramdefs CStatusBarPanel::defFnNames[] = {
	{{"SelectPanels","ВыбратьПанели"}, TRUE, 0},
	{{"GetPanel","ПолучитьПанель"}, TRUE, 0},
	{{"FindByCode","НайтиПоКоду"}, TRUE, 1},
	{{"FindByIndex","НайтиПоИндексу"}, TRUE, 1},
	{{"FindByName","НайтиПоНаименованию"}, TRUE, 1},
	{{"AddPanel","ДобавитьПанель"}, TRUE, 5},
	{{"DeletePanel","УдалитьПанель"}, TRUE, 0},
	{{"MovePanel","СдвинутьПанель"}, FALSE, 1},
	{{"AddImages","ДобавитьКартинки"}, FALSE, 1},
	{{"ImagesCount","КоличествоКартинок"}, TRUE, 0},
	{NULL,0,0}
};

struct CStatusBarPanel::parampropdefs CStatusBarPanel::defPropNames[] = {
	{{"Code","Код"}, TRUE, FALSE, NULL},
	{{"Width","Ширина"}, TRUE, TRUE, NULL},
	{{"Name","Наименование"}, TRUE, TRUE, NULL},
	{{"Caption","Заголовок"}, TRUE, TRUE, NULL},
	{{"Visible","Видимость"}, TRUE, TRUE, NULL},
	{{"System","Системная"}, TRUE, FALSE, NULL},
	{{"Style","Стиль"}, TRUE, TRUE, NULL},
	{{"FullStyle","ПолныйСтиль"}, TRUE, FALSE, NULL},
	{{"Stretch","Растягиваемая"}, TRUE, TRUE, NULL},
	{{"Position","Позиция"}, TRUE, FALSE, NULL},
	{{"ImageIndex","ИндексКартинки"}, TRUE, TRUE, NULL},
	{{"Progress","Прогресс"}, TRUE, FALSE, NULL},
	{{"HandleForProgress","ДескрипторДляПрогресса"}, TRUE, FALSE, NULL},
	{NULL,0,0, NULL}
};

CStatusBarPanel::CStatusBarPanel():CBLContext()
{
	m_pCurrentPane = NULL;
	m_iCurrentPaneIndex = -1;
	m_ProgressBar.SetParentContext(this);
}

CStatusBarPanel::~CStatusBarPanel()
{
}

int  CStatusBarPanel::GetPropVal(int iPropNum,class CValue & rValue)const
{
	if(m_pCurrentPane == NULL)
		RuntimeError("Панель не выбрана!");

	switch (iPropNum) {
	case propPaneID:
	{
		rValue = m_pCurrentPane->ID;
		break;
	}
	case propWidth:
	{
		rValue = m_pCurrentPane->Width;
		break;
	}
	case propCaption:
	{
		rValue = m_pCurrentPane->Caption;
		/*
		if(m_pCurrentPane->System)
		{
			SECStatusBar* pStatus = CStatusBarManager::GetAppStatusBar();
			if(pStatus)
			{
				int n = pStatus->CommandToIndex(m_pCurrentPane->ID);
				if(n >= 0)
				{
					CString csTitle;
					pStatus->GetPaneText(n, csTitle);
					rValue = csTitle;
					m_pCurrentPane->Caption = csTitle;
					//pBkEndUI->DoMessageLine(csTitle);
					//pBkEndUI->DoMessageLine("title updated");
				}
			}
		}
		*/
		break;
	}
	case propName:
	{
		rValue = m_pCurrentPane->Name;
		break;
	}
	case propVisible:
	{
		rValue = m_pCurrentPane->Visible;
		break;
	}
	case propSystem:
	{
		rValue = m_pCurrentPane->System;
		break;
	}
	case propPosition:
	{
		rValue = CInitFormEx::Get().pStatusBarManager->GetPanePosition(m_pCurrentPane);
		break;
	}
	case propStyle:
	{
		switch (m_pCurrentPane->Style)
		{
			case SBPS_NORMAL:
				rValue = 0L;
				break;
			case SBPS_NOBORDERS:
				rValue = 1;
				break;
			case SBPS_POPOUT:
				rValue = 2;
				break;
			case SBPS_NORMAL|SBPS_STRETCH:
				rValue = 0L;
				break;
			case SBPS_NOBORDERS|SBPS_STRETCH:
				rValue = 1;
				break;
			case SBPS_POPOUT|SBPS_STRETCH:
				rValue = 2;
				break;
		}
		break;
	}
	case propFullStyle:
	{
		rValue = m_pCurrentPane->Style;
		break;
	}
	case propStretch:
	{
		rValue = m_pCurrentPane->Stretch;
		break;
	}
	case propImageIndex:
	{
		rValue = m_pCurrentPane->ImageIndex+1;
		break;
	}
	case propProgress:
	{
		rValue.AssignContext((CBLContext*)&m_ProgressBar);
		break;
	}
	case propHandleForProgress:
	{
		SECStatusBar* pStatus = (SECStatusBar*)CStatusBarManager::GetAppStatusBar();
		if(pStatus == NULL)
			rValue = 0L;
		else
		{
			RECT rect;
			int index = pStatus->CommandToIndex(m_pCurrentPane->ID);
			pStatus->GetItemRect(index,&rect);
			CString stResult = "";
			stResult.Format("%08x%04x%04x%04x%04x", (DWORD)pStatus->m_hWnd, rect.top, rect.left, rect.bottom, rect.right);
			rValue = stResult;
		}
		break;
	}
	default:
		return S_FALSE;
	};
	return S_OK;
}

int  CStatusBarPanel::SetPropVal(int iPropNum,class CValue const & vValue)
{
	if(m_pCurrentPane == NULL)
		RuntimeError("Панель не выбрана!");

	switch (iPropNum) {
		case propWidth:
		{
			m_pCurrentPane->Width = vValue.GetNumeric();
			break;
		}
		case propCaption:
		{
			if(!m_pCurrentPane->System)
				m_pCurrentPane->Caption = vValue.GetString();
			break;
		}
		case propName:
		{
			if(!m_pCurrentPane->System)
				m_pCurrentPane->Name = vValue.GetString();
			break;
		}
		case propVisible:
		{
			m_pCurrentPane->Visible = ((UINT)vValue.GetNumeric() != 0L);
			break;
		}
		case propStyle:
		{
			/*
			SBPS_NOBORDERS Нет 3-D границы вокруг панели.
			SBPS_POPOUT обратная граница, чтобы текст "выскакивали".
			SBPS_DISABLED Не рисуйте текст.
			SBPS_STRETCH растяжек для заполнения неиспользуемого пространства. Только одна панель на бар статуса может иметь этот стиль.
			SBPS_NORMAL Нет стрейч, границы, или всплывающие.

			#define SBPS_NORMAL     0x0000
			#define SBPS_NOBORDERS  SBT_NOBORDERS
			#define SBPS_POPOUT     SBT_POPOUT
			#define SBPS_OWNERDRAW  SBT_OWNERDRAW
			#define SBPS_DISABLED   0x04000000
			#define SBPS_STRETCH    0x08000000  // stretch to fill status bar

			#define SBT_OWNERDRAW            0x1000
			#define SBT_NOBORDERS            0x0100
			#define SBT_POPOUT               0x0200
			*/
			switch ((UINT)vValue.GetNumeric())
			{
				case 0:
					m_pCurrentPane->Style = SBPS_NORMAL;
					break;
				case 1:
					m_pCurrentPane->Style = SBPS_NOBORDERS;
					break;
				case 2:
					m_pCurrentPane->Style = SBPS_POPOUT;
					break;
				default:
					m_pCurrentPane->Style = SBPS_NORMAL;
			}
			if(m_pCurrentPane->Stretch)
				m_pCurrentPane->Style |= SBPS_STRETCH;

			break;
		case propStretch:
		{
			if(((UINT)vValue.GetNumeric() != 0L))
				CInitFormEx::Get().pStatusBarManager->SetStretchPane(m_pCurrentPane);
			else
				CInitFormEx::Get().pStatusBarManager->SetStretchPane(NULL);
			break;
		}
		case propImageIndex:
		{
			int iImageIndex = vValue.GetNumeric();
			if(iImageIndex < 0) iImageIndex = 0;
			iImageIndex--;
			m_pCurrentPane->ImageIndex = iImageIndex;
			if(iImageIndex >= 0)
				m_pCurrentPane->Style |= SBPS_OWNERDRAW;
			else
				m_pCurrentPane->Style &= ~SBPS_OWNERDRAW;

			CInitFormEx::Get().pStatusBarManager->Invalidate();
			break;
		}
	}
	default:
		return S_FALSE;
	};

	CInitFormEx::Get().pStatusBarManager->UpdateElements();
	
	return S_OK;
}

int  CStatusBarPanel::CallAsFunc(int iMethNum,class CValue & rValue,class CValue **ppValue)
{
	switch (iMethNum)
	{
		case methSelectPanels:
		{
			if(CInitFormEx::Get().pStatusBarManager->GetPaneCount() == 0)
				rValue = 0L;
			else
			{
				rValue = 1;
				m_pCurrentPane = NULL;
				m_iCurrentPaneIndex = 0;
				CInitFormEx::Get().pStatusBarManager->UpdateElements();
			}
			break;
		}
		case methGetPanel:
		{
			if(m_iCurrentPaneIndex == -1)
				//RuntimeError("Выборка панелей не открыта!");
				rValue = 0L;
			else if(CInitFormEx::Get().pStatusBarManager->GetPaneCount() > m_iCurrentPaneIndex)
			{
				rValue = 1;
				m_pCurrentPane = CInitFormEx::Get().pStatusBarManager->GetPaneByIndex(m_iCurrentPaneIndex);
				m_iCurrentPaneIndex++;
			}
			else
			{
				rValue = 0L;
				m_pCurrentPane = NULL;
				m_iCurrentPaneIndex = -1;
			}
			break;
		}
		case methGetPanelByCode:
		{
			m_pCurrentPane = CInitFormEx::Get().pStatusBarManager->GetPaneByID((UINT)ppValue[0]->GetNumeric());
			if(m_pCurrentPane == NULL) rValue = 0L;
			else rValue = 1;
			break;
		}
		case methGetPanelByIndex:
		{
			m_pCurrentPane = CInitFormEx::Get().pStatusBarManager->GetPaneByIndex((UINT)ppValue[0]->GetNumeric());
			if(m_pCurrentPane == NULL) rValue = 0L;
			else rValue = 1;
			break;
		}
		case methGetPanelByName:
		{
			m_pCurrentPane = CInitFormEx::Get().pStatusBarManager->GetPaneByName(ppValue[0]->GetString());
			if(m_pCurrentPane == NULL) rValue = 0L;
			else rValue = 1;
			break;
		}
		case methAddPanel:
		{
			CString csName = ppValue[0]->GetString();
			CString csCaption = ppValue[1]->GetString();
			int iWidth = ppValue[2]->GetNumeric();
			int iStyle = ppValue[3]->GetNumeric();
			BOOL bVisible = ((UINT)ppValue[4]->GetNumeric() != 0L);

			UINT uiPaneID = CInitFormEx::Get().pStatusBarManager->AddPane(csCaption, csName, iWidth, iStyle, -1, bVisible);
			m_pCurrentPane = CInitFormEx::Get().pStatusBarManager->GetPaneByID(uiPaneID);
			rValue = uiPaneID;

			break;
		}
		case methDeletePanel:
		{
			if(m_pCurrentPane == NULL)
				RuntimeError("Панель не выбрана!");

			CInitFormEx::Get().pStatusBarManager->DeletePane(m_pCurrentPane->ID);
			rValue = 1;
			break;
		}
		case methImagesCount:
		{
			rValue = CInitFormEx::Get().pStatusBarManager->m_ImageList.GetImageCount();
			break;
		}
		default:
			return S_FALSE;
	};
	return S_OK;
}

int  CStatusBarPanel::CallAsProc(int iMethNum,class CValue * * ppValue)
{
	switch (iMethNum)
	{
		case methMovePanel:
			{
				if(m_pCurrentPane == NULL)
					RuntimeError("Панель не выбрана!");

				CInitFormEx::Get().pStatusBarManager->MovePanel(m_pCurrentPane->ID, ppValue[0]->GetNumeric());
				break;
			}
		case methAddImages:
			{
				CBLContext* pCont = ppValue[0]->GetContext();
				if (pCont && (CString("CPictureContext") == pCont->GetRuntimeClass()->m_lpszClassName))
				{
					CPictureHolder7 * pPictureHolder7 = &(((CPictureContext*)pCont)->m_PictureHolder7);
					if(pPictureHolder7)
					{
						CDC dc;
						CDC* DesktopDC = CWnd::GetDesktopWindow()->GetDC();
						if (dc.CreateCompatibleDC(DesktopDC))
						{
							CSize size = pPictureHolder7->GetSize();
							CBitmap bitmap;
							if (bitmap.CreateCompatibleBitmap(DesktopDC, size.cx, size.cy))
							{
								CBitmap* pOldbitmap = dc.SelectObject(&bitmap);
								CRect rect(CPoint(0,0), size);
								dc.FillSolidRect(0,0, size.cx, size.cy, RGB(0x00, 0x80, 0x80));
								pPictureHolder7->Render(dc, rect, 0, NULL);
								dc.SelectObject(pOldbitmap);
								//if (CInitFormEx::Get().pStatusBarManager->m_ImageList.Create(16, 15, ILC_COLOR32|ILC_MASK, 2, 0))
								CInitFormEx::Get().pStatusBarManager->m_ImageList.Add(&bitmap, RGB(0x00, 0x80, 0x80));
							}
						}
						CWnd::GetDesktopWindow()->ReleaseDC(DesktopDC);
					}
				}
				break;
			}
		default:
			{
				//CValue rValue;
				//return CallAsFunc(iMethNum,rValue,ppValue);
				return S_FALSE;
			}
	};
	return S_OK;
}


int  CStatusBarPanel::FindMethod(char const * lpMethodName)const
{
	int i;
	for (i = 0;i<lastMethod;i++){
		if (!stricmp(lpMethodName,defFnNames[i].Names[0]))
			return i;
		if (!stricmp(lpMethodName,defFnNames[i].Names[1]))
			return i;
	}
	return -1;
}

char const *  CStatusBarPanel::GetMethodName(int iMethodNum,int iMethodAlias)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
		return defFnNames[iMethodNum].Names[iMethodAlias];
	return 0;
}

int  CStatusBarPanel::GetNMethods(void)const
{
	return lastMethod;
}

int  CStatusBarPanel::HasRetVal(int iMethodNum)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
	{
		return defFnNames[iMethodNum].HasReturnValue;
	}
	return 0;
}

int CStatusBarPanel::GetNParams(int iMethodNum)const
{
	if ((iMethodNum>=0) && (iMethodNum<lastMethod))
		return defFnNames[iMethodNum].NumberOfParams;
	return 0;
}

int  CStatusBarPanel::GetParamDefValue(int iMethodNum,int iParamNum,class CValue * pDefValue)const
{

	switch (iMethodNum)
	{
		case methAddPanel:
			{
				switch (iParamNum)
				{
					case 0: *pDefValue = ""; break;
					case 1: *pDefValue = ""; break;
					case 2: *pDefValue = 20; break;
					case 3: *pDefValue = 0L; break;
					case 4: *pDefValue = 0L; break;
				}
				break;
			}
		default:
			return FALSE;
	};
	return TRUE;
}

void  CStatusBarPanel::DecrRef(void)
{
	CBLContext::DecrRef();
}

char const *  CStatusBarPanel::GetCode(void)const
{
	return NULL;
}

int  CStatusBarPanel::GetDestroyUnRefd(void)const
{
	return 1;
}

void  CStatusBarPanel::GetExactValue(class CValue & vParam)
{
	CBLContext::GetExactValue(vParam);
}

class CObjID   CStatusBarPanel::GetID(void)const
{
	return ObjID;
}

class CBLContextInternalData *  CStatusBarPanel::GetInternalData(void)
{

	return CBLContext::GetInternalData();

}

long  CStatusBarPanel::GetTypeID(void)const
{
	return 100;
}

char const *  CStatusBarPanel::GetTypeString(void)const
{
	return "ПанельСтрокиСостояния";
}

class CType   CStatusBarPanel::GetValueType(void)const
{
	CType tType(100);
	
	return tType;
}

void  CStatusBarPanel::IncrRef(void)
{
	CBLContext::IncrRef();
}

void  CStatusBarPanel::InitObject(class CType const & tType)
{
	CBLContext::InitObject(tType);
}

void  CStatusBarPanel::InitObject(char const * strName)
{
	CBLContext::InitObject(strName);
}

int  CStatusBarPanel::IsExactValue(void)const
{
	return 0;
}

int  CStatusBarPanel::IsOleContext(void)const
{
	return 0;
}

int  CStatusBarPanel::IsPropReadable(int iPropNum)const
{
	if ((iPropNum>=0) && (iPropNum<lastProp))
		return defPropNames[iPropNum].IsReadable;
	return 0;
}

int  CStatusBarPanel::IsPropWritable(int iPropNum)const
{
	if ((iPropNum>=0) && (iPropNum<lastProp))
		return defPropNames[iPropNum].IsWritable;
	return 0;
}

int  CStatusBarPanel::IsSerializable(void)
{
	return 0;
}

int  CStatusBarPanel::SaveToString(class CString & csStr)
{
	csStr = "";
	return 1;
}

void  CStatusBarPanel::SelectByID(class CObjID cID,long lNum)
{
	CBLContext::SelectByID(cID,lNum);
}

int  CStatusBarPanel::GetNProps(void)const
{
	return lastProp;
}

char const *  CStatusBarPanel::GetPropName(int iPropNum,int iPropAlias)const
{
	if ((iPropNum>=0) && (iPropNum<lastProp))
		return defPropNames[iPropNum].Names[iPropAlias];
	return NULL;
}

int  CStatusBarPanel::FindProp(char const * lpPropName)const
{
	int i;
	for (i = 0;i<lastProp;i++)
	{
		if (!stricmp(lpPropName,defPropNames[i].Names[0]))
			return i;
		if (!stricmp(lpPropName,defPropNames[i].Names[1]))
			return i;
	}
	return -1;
}

