﻿var LayoutCells = new Class(
{
	initialize: function()
	{
		this.cells = [];  // Is a 2 dimensional array - an item contains an object of an array of cells and the parent element
		this.cellSizes = {};
		this.smartPadding = 0;

		ui.registerResizeHandler(this.resizeCells);
		ui.registerCleanupHandler(this.removeCells);
	},

	getCellElement: function(cell)
	{
		return ui.getNestedControl(cell.DialogID, cell.ControlID);
	},

	initControl: function(dialogID, controlID, kind, unit, width, height)
	{
		var lcControl = null;
		var lcParent = null;

		try
		{
			lcControl = ui.getNestedControl(dialogID, controlID);
			//lcParent = lcControl.getParent(".layoutCell");
			lcParent = lcControl.getParent();
		}
		catch (e)
		{
			return;
		}

		if (lcControl == null || lcParent == null)
		{
			return;
		}

		var cell =
		{
			"DialogID": dialogID,
			"ControlID": controlID,
			"Kind": kind,
			"Unit": unit,
			"Width": width,
			"Height": height,
			"Size": { "x": 0, "y": 0 },
			"SubCells": []
		};

		lcControl.store("Cell", cell);

		var lcParentLC = lcControl.getParent(".layoutCell");

		var cells = [];

		if (lcParentLC != null && lcParentLC.retrieve("Cell") != null)
		{
			// found a parent layout cell - if distance > 1 lcParent points to the parent layout cell
			//			if (lcParent != lcParentLC)
			//			{
			//				lcParent["Cell"] = lcParentLC["Cell"];
			//				document.title += ", " + lcParent.id;
			//			}
			//lcParent["Cells"] = cells;
			//layoutCells.cells.push( { "Cells" : cells, "Parent" : lcParent } );
			cells = lcParentLC.retrieve("Cell").SubCells;
		}
		else
		{
			if (lcParent.retrieve("Cells") != null)
			{
				// parent element is not a cell, but already contains cells
				cells = lcParent.retrieve("Cells");
			}
			else
			{
				lcParent.store("Cells", cells);
				layoutCells.cells.push({ "Cells": cells, "Parent": lcParent });
			}
		}

		cells.push(cell);
	},

	resizeCells: function()
	{
		for (var i = 0; i < layoutCells.cells.length; i++)
		{
			var cells = layoutCells.cells[i];

			var parentSize = cells.Parent.getSize();

			if (parentSize.y == 0)
			{
				var wndHeight = window.getScrollSize().y;
				if (parentSize.y < wndHeight)
				{
					parentSize.y = wndHeight;
				}
			}

			layoutCells.calculateCellSizes(cells.Cells, parentSize);
			layoutCells.refreshCells(cells.Cells);
		}
	},

	calculateCellSize: function(cell, parentSize, usedWidth, usedHeight)
	{
		var cellWidth = 0;
		var cellHeight = 0;

		switch (cell.Kind)
		{
			// Column 
			case 0:
				switch (cell.Unit)
				{
					// Pixel 
					case 0:
						cellWidth = cell.Width;
						break;

					// Percent 
					case 1:
						cellWidth = parentSize.x * (cell.Width / 100);
						break;

					// Fill 
					case 2:
						cellWidth = (parentSize.x - usedWidth) * cell.Width;
						break;
				}

				cellHeight = parentSize.y;

				break;

			// Row 
			case 1:
				switch (cell.Unit)
				{
					// Pixel 
					case 0:
						cellHeight = cell.Height;
						break;

					// Percent 
					case 1:
						cellHeight = parentSize.y * (cell.Height / 100);
						break;

					// Fill 
					case 2:
						cellHeight = (parentSize.y - usedHeight) * cell.Height;
						break;
				}

				cellWidth = parentSize.x;

				break;

			// Cell 
			case 2:
				cellWidth = parentSize.x;
				cellHeight = parentSize.y;

				break;
		}

		if (cellWidth < 0)
		{
			cellWidth = 0;
		}

		if (cellHeight < 0)
		{
			cellHeight = 0;
		}

		return { x: cellWidth, y: cellHeight };
	},

	determineCellSizeByContent: function(cell)
	{
		var width = 0;
		var height = 0;

		var lcControl = ui.getNestedControl(cell.DialogID, cell.ControlID);

		if (lcControl != null)
		{
			var sizers = lcControl.getElements(".lcSizer");

			for (var i = 0; i < sizers.length; i++)
			{
				var sizerHeight = sizers[i].getSize().y + sizers[i].getStyle("top").toInt();

				if (sizerHeight > height)
				{
					height = sizerHeight;
				}
			}
		}

		return { "x": width, "y": height };
	},

	calculateCellSizes: function(cells, parentSize)
	{
		var usedWidth = 0;
		var usedHeight = 0;

		switch (cells[0].Kind)
		{
			case 0:
				usedWidth = (cells.length - 1) * layoutCells.smartPadding;
				break;
			case 1:
				usedHeight = (cells.length - 1) * layoutCells.smartPadding;
				break;
		}

		// Get fixed cell sizes
		for (var i = 0; i < cells.length; i++)
		{
			var cell = cells[i];

			if (cell.Unit == 2) continue;

			var cellSize = layoutCells.calculateCellSize(cell, parentSize, usedWidth, usedHeight);
			var cellSizeByDialogs = layoutCells.determineCellSizeByContent(cell);

			if (cellSize.x < cellSizeByDialogs.x)
			{
				cellSize.x = cellSizeByDialogs.x;
			}

			if (cellSize.y < cellSizeByDialogs.y)
			{
				cellSize.y = cellSizeByDialogs.y;
			}

			switch (cell.Kind)
			{
				case 0:
					usedWidth += cellSize.x;
					break;
				case 1:
					usedHeight += cellSize.y;
					break;
			}

			cell.Size = cellSize;
		}

		// Get dynamic cell sizes
		for (var d = 0; d < cells.length; d++)
		{
			var dynamicCell = cells[d];

			if (dynamicCell.Unit != 2) continue;

			var dynamicCellSizeByDialogs = layoutCells.determineCellSizeByContent(dynamicCell);
			var dynamicCellSize = layoutCells.calculateCellSize(dynamicCell, parentSize, usedWidth, usedHeight);

			if (dynamicCellSize.x < dynamicCellSizeByDialogs.x)
			{
				dynamicCellSize.x = dynamicCellSizeByDialogs.x;
			}

			if (dynamicCellSize.y < dynamicCellSizeByDialogs.y)
			{
				dynamicCellSize.y = dynamicCellSizeByDialogs.y;
			}

			dynamicCell.Size = dynamicCellSize;
		}

		for (var e = 0; e < cells.length; e++)
		{
			if (cells[e].SubCells.length > 0)
			{
				layoutCells.calculateCellSizes(cells[e].SubCells, cells[e].Size);

				var cellHeight = cells[e].Size.y;
				var childHeight = 0;

				for (var c = 0; c < cells[e].SubCells.length; c++)
				{
					if (cells[e].SubCells[c].Kind != 1)
					{
						if (childHeight < cells[e].SubCells[c].Size.y)
						{
							childHeight = cells[e].SubCells[c].Size.y;
						}
					}
					else
					{
						childHeight += cells[e].SubCells[c].Size.y;

						if (c < cells[e].SubCells.length - 1)
						{
							childHeight += layoutCells.smartPadding;
						}
					}
				}

				if (cellHeight < childHeight)
				{
					cellHeight = childHeight;
				}

				cells[e].Size.y = cellHeight;
			}
		}
	},

	removeCells: function(rootElement)
	{
		var filteredCellContainers = [];

		for (var i = 0; i < layoutCells.cells.length; i++)
		{
			var cellContainer = layoutCells.cells[i];

			if (!rootElement.hasChild(cellContainer.Parent) && (cellContainer.Parent != rootElement))
			{
				filteredCellContainers.push(cellContainer);
			}
		}

		var rootCell = rootElement.retrieve("Cell");

		if (rootCell != null)
		{
			rootCell.SubCells = [];
		}

		layoutCells.cells = filteredCellContainers;
	},

	refreshCells: function(cells)
	{
		var left = 0;
		var top = 0;

		// Resize and position cells
		for (var c = 0; c < cells.length; c++)
		{
			var cell = cells[c];
			var cellPadding = layoutCells.smartPadding;

			if (c == cell.length - 1)
			{
				cellPadding = 0;
			}

			var cellDiv = layoutCells.getCellElement(cell);

			if (left < 0)
			{
				left = 0;
			}

			cellDiv.setStyle("left", left);
			cellDiv.setStyle("top", top);
			cellDiv.setStyle("width", cell.Size.x);
			cellDiv.setStyle("height", cell.Size.y);

			switch (cell.Kind)
			{
				case 0:
					left += cell.Size.x + cellPadding;
					break;
				case 1:
					top += cell.Size.y + cellPadding;
					break;
			}

			if (cell.SubCells.length > 0)
			{
				layoutCells.refreshCells(cell.SubCells);
			}
		}
	}
});

var layoutCells = new LayoutCells();