/*

Miranda NG: the free IM client for Microsoft* Windows*

Copyright (�) 2012-16 Miranda NG project (http://miranda-ng.org),
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.

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.
*/

#include "stdafx.h"

void RefreshTree(HWND hwndDlg, HTREEITEM hti);
static char* rowOptTmplStr;
static ROWCELL* rowOptTmplRoot;
static ROWCELL* rowOptTA[100];
wchar_t *types[] = {
	L"none", L"text1", L"text2", L"text3", L"status",
	L"avatar", L"extra", L"extra1", L"extra2", L"extra3",
	L"extra4", L"extra5", L"extra6", L"extra7", L"extra8",
	L"extra9", L"time", L"space", L"fspace"
};

RECT da = { 205, 58, 440, 130 }; // Draw area

void rowOptBuildTA(pROWCELL cell, pROWCELL* TA, int* i)
{
	if (!cell) return;
	TA[(*i)++] = cell;
	rowOptBuildTA(cell->child, TA, i);
	rowOptBuildTA(cell->next, TA, i);
}

void rowOptShowSettings(HWND hwnd)
{
	TVITEM tvi;
	pROWCELL cell;
	HTREEITEM node = TreeView_GetSelection(GetDlgItem(hwnd, IDC_ROWTREE));
	int param;

	tvi.hItem = node;
	tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

	TreeView_GetItem(GetDlgItem(hwnd, IDC_ROWTREE), &tvi);
	cell = (pROWCELL)tvi.lParam;

	if (!tvi.hItem)  {
		EnableWindow(GetDlgItem(hwnd, IDC_CONTTYPE), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_VALIGN), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_HALIGN), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 0);
		SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, 0);
		SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, 0);
		EnableWindow(GetDlgItem(hwnd, IDC_CONTLAYER), 0);
		return;
	}

	EnableWindow(GetDlgItem(hwnd, IDC_CONTTYPE), 1);
	EnableWindow(GetDlgItem(hwnd, IDC_VALIGN), 1);
	EnableWindow(GetDlgItem(hwnd, IDC_HALIGN), 1);
	EnableWindow(GetDlgItem(hwnd, IDC_CONTLAYER), 1);

	if (cell->type != TC_SPACE && cell->type != TC_FIXED) {
		EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 0);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 0);
		SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, 0);
		SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, 0);
	}
	else {
		EnableWindow(GetDlgItem(hwnd, IDC_CONTWIDTH), 1);
		EnableWindow(GetDlgItem(hwnd, IDC_CONTHEIGHT), 1);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTWIDTH), 1);
		EnableWindow(GetDlgItem(hwnd, IDC_SPINCONTHEIGHT), 1);
		SendDlgItemMessage(hwnd, IDC_SPINCONTWIDTH, UDM_SETPOS, 0, MAKELONG(cell->w, 0));
		SendDlgItemMessage(hwnd, IDC_SPINCONTHEIGHT, UDM_SETPOS, 0, MAKELONG(cell->h, 0));
	}

	SendDlgItemMessage(hwnd, IDC_CONTTYPE, CB_SETCURSEL, cell->type, 0);

	switch (cell->valign) {
	case TC_VCENTER:
		param = 1;
		break;
	case TC_BOTTOM:
		param = 2;
		break;
	default:
		param = 0;
	}
	SendDlgItemMessage(hwnd, IDC_VALIGN, CB_SETCURSEL, param, 0);

	switch (cell->halign) {
	case TC_HCENTER:
		param = 1;
		break;
	case TC_RIGHT:
		param = 2;
		break;
	default:
		param = 0;
	}
	SendDlgItemMessage(hwnd, IDC_HALIGN, CB_SETCURSEL, param, 0);

	CheckDlgButton(hwnd, IDC_CONTLAYER, cell->layer ? BST_CHECKED : BST_UNCHECKED);
}

void rowOptGenerateTreeView(pROWCELL cell, HTREEITEM node, HWND hwnd)
{
	if (!cell) return;

	TVINSERTSTRUCT tvis;
	tvis.hParent = node;
	tvis.hInsertAfter = TVI_LAST;
	tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	tvis.item.stateMask = TVIS_STATEIMAGEMASK;
	tvis.item.lParam = (LPARAM)cell;

	switch (cell->cont) {
	case TC_ROW:
		tvis.item.pszText = L"Line";
		break;
	case TC_COL:
		tvis.item.pszText = L"Column";
	}

	tvis.item.iImage = cell->child ? 1 : 2;
	tvis.item.iSelectedImage = cell->child ? 0 : 2;

	HTREEITEM pnode = TreeView_InsertItem(hwnd, &tvis);
	rowOptGenerateTreeView(cell->child, pnode, hwnd);
	rowOptGenerateTreeView(cell->next, node, hwnd);
}

int rowOptFillRowTree(HWND hwnd)
{
	TreeView_DeleteAllItems(hwnd);
	rowOptGenerateTreeView(rowOptTmplRoot, NULL, hwnd);
	TreeView_Expand(hwnd, TreeView_GetRoot(hwnd), TVM_EXPAND);
	return 0;
}

void rowOptAddContainer(HWND htree, HTREEITEM hti)
{
	TVINSERTSTRUCT tvis;
	TVITEM tviparent;
	ROWCELL *cell = NULL;

	if (!hti) {
		if (TreeView_GetRoot(htree))
			return;

		rowAddCell(rowOptTmplRoot, TC_ROW);
		tvis.hParent = NULL;
		tvis.hInsertAfter = TVI_ROOT;
		tvis.item.pszText = L"Line";
		tvis.item.lParam = (LPARAM)rowOptTmplRoot;
		cell = rowOptTmplRoot;
	}
	else {
		// Get parent item
		tviparent.hItem = hti;
		tviparent.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		TreeView_GetItem(htree, &tviparent);
		cell = (pROWCELL)tviparent.lParam;

		if (cell->cont == TC_ROW)
			tvis.item.pszText = L"Column";
		else
			tvis.item.pszText = L"Line";

		if (cell->child) {
			cell = cell->child;

			while (cell->next)
				cell = cell->next;

			rowAddCell(cell->next, ((ROWCELL*)tviparent.lParam)->cont == TC_ROW ? TC_COL : TC_ROW);
			cell = cell->next;
		}
		else {
			rowAddCell(cell->child, ((ROWCELL*)tviparent.lParam)->cont == TC_ROW ? TC_COL : TC_ROW);
			cell = cell->child;
		}

		tvis.hInsertAfter = TVI_LAST;
	}

	tvis.item.lParam = (LPARAM)cell;
	tvis.hParent = hti;

	tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	tvis.item.stateMask = TVIS_STATEIMAGEMASK;
	tvis.item.iImage = 2;
	tvis.item.iSelectedImage = 2;

	TreeView_InsertItem(htree, &tvis);

	TreeView_Expand(htree, hti, TVM_EXPAND);

	// Change icon at parent item
	tviparent.iImage = 1;
	tviparent.iSelectedImage = 0;
	TreeView_SetItem(htree, &tviparent);

	int i = 0;
	memset(rowOptTA, 0, sizeof(rowOptTA));
	rowOptBuildTA(rowOptTmplRoot, (pROWCELL*)&rowOptTA, &i);
}

void rowOptDelContainer(HWND htree, HTREEITEM hti)
{
	HTREEITEM prev = TreeView_GetPrevSibling(htree, hti);
	HTREEITEM prnt = TreeView_GetParent(htree, hti);
	TVITEM	  tvi, tvpi;

	if (!hti) return;

	// Get current tree item
	tvi.hItem = hti;
	tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	TreeView_GetItem(htree, &tvi);

	tvpi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;

	if (prev)
	{
		tvpi.hItem = prev;
		TreeView_GetItem(htree, &tvpi);
		((pROWCELL)tvpi.lParam)->next = ((pROWCELL)tvi.lParam)->next;
	}
	else
	{
		if (prnt)
		{
			tvpi.hItem = prnt;
			TreeView_GetItem(htree, &tvpi);
			((pROWCELL)tvpi.lParam)->child = ((pROWCELL)tvi.lParam)->next;
			prev = prnt;
		}
		else
		{

			tvpi.lParam = 0;
			rowOptTmplRoot = (pROWCELL)tvpi.lParam;
		}

	}

	((pROWCELL)tvi.lParam)->next = NULL;
	rowDeleteTree((pROWCELL)tvi.lParam);

	{
		int i = 0;
		memset(rowOptTA, 0, sizeof(rowOptTA));
		rowOptBuildTA((pROWCELL)tvpi.lParam, (pROWCELL*)&rowOptTA, &i);
	}

	TreeView_DeleteItem(htree, hti);


	// Change icon at parent item
	if (!prnt || (prnt != prev)) return;

	if (TreeView_GetChild(htree, prnt))
	{
		tvpi.iImage = 1;
		tvpi.iSelectedImage = 0;
	}
	else
	{
		tvpi.iImage = 2;
		tvpi.iSelectedImage = 2;
	}
	TreeView_SetItem(htree, &tvpi);

}

void RefreshTree(HWND hwndDlg, HTREEITEM hti)
{
	HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE);
	pROWCELL  cell;
	TVITEM    tvi = { 0 };
	if (hti == NULL) hti = TreeView_GetRoot(htree);
	while (hti)
	{
		tvi.hItem = hti;
		tvi.mask = TVIF_HANDLE;//|TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
		TreeView_GetItem(htree, &tvi);
		cell = (pROWCELL)tvi.lParam;
		if (cell)
		{
			wchar_t buf[200] = { 0 };
			if (!cell->child)
			{
				if (cell->type == 0)
					mir_snwprintf(buf, TranslateT("Empty %s cell"), cell->cont == TC_COL ? TranslateT("column") : TranslateT("line"));
				else
					mir_wstrncpy(buf, TranslateW(types[cell->type]), _countof(buf));
			}
			else
			{
				if (cell->type == 0)
					mir_wstrncpy(buf, (cell->cont != TC_COL ? TranslateT("columns") : TranslateT("lines")), _countof(buf));
				else
					mir_snwprintf(buf, TranslateT("%s, contain %s"), TranslateW(types[cell->type]), cell->cont != TC_COL ? TranslateT("columns") : TranslateT("lines"));
			}
			if (cell->layer) mir_wstrncat(buf, TranslateT(" layered"), _countof(buf) - mir_wstrlen(buf));
			tvi.mask = TVIF_HANDLE | TVIF_TEXT;
			tvi.pszText = buf;
			TreeView_SetItem(htree, &tvi);
		}
		{
			HTREEITEM child_hti = TreeView_GetChild(htree, hti);
			if (child_hti) RefreshTree(hwndDlg, child_hti);
		}
		hti = TreeView_GetNextSibling(htree, hti);
	}

	RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN);
}

INT_PTR CALLBACK DlgTmplEditorOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
	{
		int hbuf = 0, seq = 0;
		HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE);

		TranslateDialogDefault(hwndDlg);
		rowOptTmplStr = db_get_sa(NULL, "ModernData", "RowTemplate");
		if (!rowOptTmplStr)
			rowOptTmplStr = mir_strdup("<TR />");

		SendDlgItemMessage(hwndDlg, IDC_SPINCONTWIDTH, UDM_SETRANGE, 0, MAKELONG(999, 0));
		SendDlgItemMessage(hwndDlg, IDC_SPINCONTHEIGHT, UDM_SETRANGE, 0, MAKELONG(999, 0));

		int i, item;

		for (i = 0; i < _countof(types); i++) {
			item = SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_ADDSTRING, 0, (LPARAM)TranslateW(types[i]));
			SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_SETITEMDATA, item, 0);
		}
		SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_SETCURSEL, 0, 0);

		wchar_t *h_alignment[] = { L"left", L"hCenter", L"right" };
		for (i = 0; i < _countof(h_alignment); i++) {
			item = SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_ADDSTRING, 0, (LPARAM)TranslateW(h_alignment[i]));
			SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_SETITEMDATA, item, 0);
		}
		SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_SETCURSEL, 0, 0);

		wchar_t *v_alignment[] = { L"top", L"vCenter", L"bottom" };
		for (i = 0; i < _countof(v_alignment); i++) {
			item = SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_ADDSTRING, 0, (LPARAM)TranslateW(v_alignment[i]));
			SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_SETITEMDATA, item, 0);
		}
		SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_SETCURSEL, 0, 0);

		rowDeleteTree(rowOptTmplRoot);
		rowOptTmplRoot = NULL;
		rowParse(rowOptTmplRoot, rowOptTmplRoot, rowOptTmplStr, hbuf, seq, rowOptTA);
		seq = 0;
		memset(rowOptTA, 0, sizeof(rowOptTA));
		rowOptBuildTA(rowOptTmplRoot, (pROWCELL*)&rowOptTA, &seq);

		rowOptFillRowTree(htree);
		RefreshTree(hwndDlg, NULL);
		TreeView_SelectItem(GetDlgItem(hwndDlg, IDC_ROWTREE), TreeView_GetRoot(GetDlgItem(hwndDlg, IDC_ROWTREE)));
		rowOptShowSettings(hwndDlg);
	}
	return TRUE;

	case WM_COMMAND:
	{
		HWND htree = GetDlgItem(hwndDlg, IDC_ROWTREE);
		pROWCELL  cell;
		TVITEM    tvi = { 0 };
		HTREEITEM hti = TreeView_GetSelection(htree);


		tvi.hItem = hti;
		tvi.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
		TreeView_GetItem(htree, &tvi);
		cell = (pROWCELL)tvi.lParam;

		switch (LOWORD(wParam)) {
		case IDC_CONTTYPE:
			if (HIWORD(wParam) == CBN_SELENDOK) {
				int index = SendDlgItemMessage(hwndDlg, IDC_CONTTYPE, CB_GETCURSEL, 0, 0);
				cell->type = index;
				RefreshTree(hwndDlg, NULL);
			}

		case IDC_VALIGN:
			if (HIWORD(wParam) == CBN_SELENDOK) {
				switch (SendDlgItemMessage(hwndDlg, IDC_VALIGN, CB_GETCURSEL, 0, 0)) {
				case 0:
					cell->valign = TC_TOP;
					break;
				case 1:
					cell->valign = TC_VCENTER;
					break;
				case 2:
					cell->valign = TC_BOTTOM;
					break;
				}
				RefreshTree(hwndDlg, NULL);
			}

		case IDC_HALIGN:
			if (HIWORD(wParam) == CBN_SELENDOK) {
				switch (SendDlgItemMessage(hwndDlg, IDC_HALIGN, CB_GETCURSEL, 0, 0)) {
				case 0:
					cell->halign = TC_LEFT;
					break;
				case 1:
					cell->halign = TC_HCENTER;
					break;
				case 2:
					cell->halign = TC_RIGHT;
					break;
				}
				RefreshTree(hwndDlg, NULL);
			}
		}

		if (HIWORD(wParam) == BN_CLICKED) {
			if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_ADDCONTAINER))
				// Adding new container
			{
				rowOptAddContainer(htree, hti);
			}
			else if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_DELCONTAINER))
				// Deleting container
			{
				rowOptDelContainer(htree, hti);
			}
			else if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_CONTUP))
				// Moving container to up
			{
				RedrawWindow(htree, &da, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN);
			}
			RefreshTree(hwndDlg, NULL);
			RedrawWindow(GetParent(hwndDlg), NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN);
		}
		return TRUE;
	}

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case IDC_ROWTREE:
			if (((LPNMHDR)lParam)->code == NM_SETCURSOR)
				rowOptShowSettings(hwndDlg);
			if (((LPNMHDR)lParam)->code == NM_CLICK)
				RedrawWindow(hwndDlg, &da, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW);
			break;

		case 0: // Apply or Ok button is pressed
			return FALSE; // Temporary
			break;
		}
		return TRUE;

	case WM_PAINT:
		if (rowOptTmplRoot) {
			int i = 0;

			// Drawning row template at properties page
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwndDlg, &ps);

			TVITEM curItem;
			curItem.hItem = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_ROWTREE));
			curItem.mask = TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
			TreeView_GetItem(GetDlgItem(hwndDlg, IDC_ROWTREE), &curItem);

			while (rowOptTA[i]) {
				switch (rowOptTA[i]->type) {
				case TC_AVATAR:
					rowOptTA[i]->w = 25;
					rowOptTA[i]->h = 30;
					break;

				case TC_STATUS:
				case TC_EXTRA1:
				case TC_EXTRA2:
				case TC_EXTRA3:
				case TC_EXTRA4:
				case TC_EXTRA5:
				case TC_EXTRA6:
				case TC_EXTRA7:
				case TC_EXTRA8:
				case TC_EXTRA9:
					rowOptTA[i]->w = 16;
					rowOptTA[i]->h = 16;
					break;

				case TC_EXTRA:
					rowOptTA[i]->w = 112;
					rowOptTA[i]->h = 16;
					break;

				case TC_TEXT1:
				case TC_TEXT2:
				case TC_TEXT3:
					rowOptTA[i]->w = 200;
					rowOptTA[i]->h = 16;
					break;

				case TC_TIME:
					rowOptTA[i]->w = 30;
					rowOptTA[i]->h = 10;
				default:
					rowOptTA[i]->w = 0;
					rowOptTA[i]->h = 0;
				}
				i++;
			}

			rowSizeWithReposition(rowOptTmplRoot, da.right - da.left);

			i = -1;
			while (rowOptTA[++i]) {

				switch (rowOptTA[i]->type) {
				case TC_SPACE:
				case TC_FIXED:
				case 0:
					//if (rowOptTA[i] != (pROWCELL)curItem.lParam)
					continue;
				}
				Rectangle(hdc,
					rowOptTA[i]->r.left + da.left,
					rowOptTA[i]->r.top + da.top,
					rowOptTA[i]->r.right + da.left,
					rowOptTA[i]->r.bottom + da.top);
			}

			EndPaint(hwndDlg, &ps);
			return FALSE;
		}

	}
	return FALSE;
}