<?xml version="1.0" encoding="UTF-8"?>
<!--
$RCSfile: rnmc_common_list.xml,v $
$Revision: 957 $

last change: $Date: 2009-02-17 14:00:06 +0300 (Вт, 17 фев 2009) $
             $Author: toha $

	Lacerta Project
	version 1.0.0.1
	Copyright (C) 2007-2009 RNMC
-->
<rmml>

<composition name="common_list_item">
<script><![CDATA[
	this.columnsWidth = new Array();
  this.columnsPadding = new Array();
	this.rowsTotal = 0;
	this.rows = new Array();
// доступность элемента списка
// 	(если доступен то при установленной подсветке будет посвечиваться)
	this.enabled = true;

	this.itemHeight = 0;

	function update(){
	}

	function addRow(columnWidth, columnPadding){
		this.columnsWidth.push(columnWidth);
    this.columnsPadding.push(columnPadding);
		this.rowsTotal++;
	}

	function setRowObject(rowIndex, newObject){
		if(rowIndex < 0 || rowIndex >= this.rowsTotal){
trace("ERROR: Wrong row index.");
			newObject.parent = null;
			return;
		} else {
			if(this.rows[rowIndex]){
				this.rows[rowIndex].parent = null;
				this.rows[rowIndex] = null;
			}
      
			var rowObjectX = 0;
      
			for(var i = 0; i < rowIndex; i++){
				rowObjectX += parent.columnInterval;
				rowObjectX += this.columnsWidth[i];
			}
      
			newObject.parent = this;
			newObject.x = rowObjectX;
      
      newObject.x      += this.columnsPadding[rowIndex].left;
      newObject.y      += this.columnsPadding[rowIndex].top;
      newObject.width  -= this.columnsPadding[rowIndex].left + 
        this.columnsPadding[rowIndex].right;
      newObject.height -= this.columnsPadding[rowIndex].top + 
        this.columnsPadding[rowIndex].bottom;
        
      var obj_height = newObject.height + this.columnsPadding[rowIndex].top +
        this.columnsPadding[rowIndex].bottom;
      
      this.itemHeight = Math.max(this.itemHeight, obj_height);

			this.rows[rowIndex] = newObject;
		}
	}

	function showRowContent(rowIndex){
		if(rowIndex < 0 || rowIndex >= this.rowsTotal){
trace("ERROR: Wrong row index.");
			return;
		} else {
			if(this.rows[rowIndex])
				this.rows[rowIndex].visible = true;
		}
	}

	function hideRowContent(rowIndex){
		if(rowIndex < 0 || rowIndex >= this.rowsTotal){
trace("ERROR: hideRowContent: Wrong row index.");
			return;
		} else {
			if(this.rows[rowIndex])
				this.rows[rowIndex].visible = false;
		}
	}
	
	function setRowText(rowIndex, textValue){

	}

	function showItem(){
//trace("list_item.showItem()");
		this.visible = true;
	}

	function hideItem(){
//trace("list_item.hideItem()");
		this.visible = false;
	}

	function setBgColor(colorStr){
		var bgWidth = 0;
    
		if(this.bgMarker){
			this.bgMarker.parent = null;
			this.bgMarker = null;
		}
    
		this.bgMarker = new Text();
		this.bgMarker.adjustHeight = false;
		this.bgMarker.bkgColor = colorStr;
    
		for(var i = 0; i < this.columnsWidth.length; i++){
			bgWidth += this.columnsWidth[i];
		}
    
    bgWidth += parent.columnInterval*(this.columnsWidth.length-1);
    
		this.bgMarker.height = this.itemHeight;
		this.bgMarker.width = bgWidth;
		this.bgMarker.depth = 5;
		this.bgMarker.parent = this;
		this.bgMarker.visible = true;
	}
]]></script>
</composition>

<composition name="common_list">
<script event="onMouseWheel"><![CDATA[
	if(this.listHeight < this.itemsTotalHeight){
		var object = Mouse.target;
		while(object != null && object != this.parent)
			object = object.parent;
		if (object == this.parent)
		{
			var newtopIndex = this.topIndex - parseInt(Mouse.delta/120);
			if (newtopIndex < 0)
				newtopIndex = 0;
			else if (newtopIndex > this.maxIndex)
				newtopIndex = this.maxIndex;

			if (newtopIndex != this.topIndex){
				if(this.scroll){
					this.scroll.setClientPos(newtopIndex);
					this.scroll.setSliderPos(this.topIndex/this.scroll.scrollMax);
				}
				else
					this.scroll_to(newtopIndex);
			}
		}
	}
]]></script>
<button enabled="true" name="listArea" depth="-3" useHandCursor="true"/>
<script event="listArea.onRollOut">
	listRollout();
</script>
<script event="listArea.onRollOver">
	listRollover();
</script>
<xml name="xmlFile"/>
<script><![CDATA[
// =========================  настройки внешнего вида списка  ==================================
// цвет подсветки выбранного элемента
	this.selectedItemBgColor = "#C8C8C8";
// цвет подсветки текущего (под курсором) элемента
	this.currentItemBgColor = "#999999";
//подсвечивать ли текущий (под курсором) элемент
	this.markCurrent = false;
//подсвечивать ли выбранный элемента
	this.markSelected = false;
// межстрочный интервал
	this.lineInterval  = 10;
// межстолбцовый интервал
	this.columnInterval  = 10;

  // настройки растояние внутри ячейки
  this.padding = {left: 0, right: 0, top: 0, bottom: 0};
  
// ширина списка
	this.listWidth = 300;
// высота списка
	this.listHeight = 200;
// количество колонок
	this.listColumns = 0;
// ширины колонок
	this.listColumnsWidth = null;

	this.itemsTotalHeight  = 0;

// стартовая (самая верхняя из ототбражаемых) ячейка
	this.topIndex = 0;
// текущая выделенная ячейка
	this.listIndex = 0;
// текущая выделенная ячейка
	this.lastSelectedItem = -1;

// искусственное дополнение - колво итемв в низу - для облегчения работы скролла
	this.bottomIndex = 0;

	this.maxIndex = 0;

// элементы списка
	this.listItems = null;
// параметры отображенных на экране элементов
	this.screenItemsParams = null;

// начальная инициализация
	function initList(newListWidth, newListHeight, newListColumns, columnsWidth){
		this.listWidth = newListWidth;
		this.listHeight = newListHeight;
		this.listColumns = newListColumns;
		this.listColumnsWidth = new Array();
		if(columnsWidth instanceof Array && this.listColumns == columnsWidth.length){
			for(var i = 0; i < this.listColumns; i++){
				this.listColumnsWidth.push(columnsWidth[i]);
			}
		}

	// создание подсветки
		this.currentItemMarker = new Text();
		this.currentItemMarker.adjustHeight = false;
		this.currentItemMarker.x = -4;
		this.currentItemMarker.bkgColor = this.currentItemBgColor;
		this.currentItemMarker.width = this.listWidth + 8;
		this.currentItemMarker.height = 1;
		this.currentItemMarker.depth = 1;
		this.currentItemMarker.visible = false;
		this.currentItemMarker.parent = this;

	// создание подсветки текущего выбранного элемента
		this.selectedItemMarker = new Text();
		this.selectedItemMarker.adjustHeight = false;
		this.selectedItemMarker.x = -4;
		this.selectedItemMarker.bkgColor = this.selectedItemBgColor;
		this.selectedItemMarker.width = this.listWidth + 8;
		this.selectedItemMarker.height = 1;
		this.selectedItemMarker.depth = 2;
		this.selectedItemMarker.visible = false;
		this.selectedItemMarker.parent = this;

		if(!this.listItems)
			this.listItems = new Array();
		while(this.listItems.length > 0)
			this.listItems.pop().parent = null;

		this.visible = false;
	}

	function setListHeight(newListHeight){
		if(newListHeight > 0){
			this.listHeight = newListHeight;
			this.listArea.hitArea = "[0,0," + this.listWidth + "," + this.listHeight + "]";
			this.updateList();
		}
	}

	function addListItem(){
		var newListItem = new Composition();
		newListItem._class = "common_list_item";
		newListItem.parent  = this;

		for(var i = 0; i < this.listColumns; i++){
			newListItem.addRow(this.listColumnsWidth[i], this.padding);
		}
    
		this.listItems.push(newListItem);
	}	

	function setColumnWidth(columnId, columnWidth){
		if(columnId < this.listColumnsWidth.length)
			this.listColumnsWidth[columnId] = columnWidth;
	}
	
	function getColumnWidth(columnId){
		return this.listColumnsWidth[columnId];
	}

	function setRowObject(itemIndex, rowIndex, newObject){
//trace(itemIndex + " of " + this.listItems.length);
		if(itemIndex >= 0 && itemIndex < this.listItems.length){
			this.listItems[itemIndex].setRowObject(rowIndex, newObject);
		}
	}

	function showRowContent(itemIndex, rowIndex){
		if(itemIndex >= 0 && itemIndex < this.listItems.length){
			this.listItems[itemIndex].showRowContent(rowIndex);
		}
	}

	function hideRowContent(itemIndex, rowIndex){
		if(itemIndex >= 0 && itemIndex < this.listItems.length){
			this.listItems[itemIndex].hideRowContent(rowIndex);
		}
	}

	function updateList(){
		if(this.screenItemsParams)
			this.screenItemsParams = null;
		this.screenItemsParams = new Array();

		var curItemY = 0;
		var showItems = 0;
		for(var i = 0; i < this.listItems.length; i++){
			if(i < this.topIndex){
				this.listItems[i].hideItem();
			} else {
				// проверяем выйдем ли за границу списка, если покажем еще
				// один элемент
				if(curItemY + this.listItems[i].itemHeight > this.listHeight){
					// выйдем - значит спрятать все остальные (индекс которых больше или равен)
					this.hideItemsInInterval(i, this.listItems.length - 1);
					break;
				} else {
					// если не выходим еще, то показываем этот элемент
					var newItemParam = new Array();
					newItemParam[0] = i;
					newItemParam[1] = curItemY;
					this.listItems[i].y = curItemY;
					this.listItems[i].x = 0;
					curItemY += this.listItems[i].itemHeight;
					newItemParam[2] = this.listItems[i].itemHeight;
					curItemY += this.lineInterval;
					this.screenItemsParams.push(newItemParam);
					showItems++;
					this.listItems[i].showItem();
				}
			}
		}
		if(this.markSelected && this.lastSelectedItem >= 0){
			this.markSeletedItem(this.lastSelectedItem);
		}	
		this.bottomIndex = (this.listItems.length - this.topIndex) - showItems;
	}

	function showObject(){
		if(!this.scroll){
			if(this.listHeight < this.itemsTotalHeight){
				//  значит нужен скроллинг
				this.scroll = new Composition();
				this.scroll._class = "ui_CScrollerVertical";
				this.scroll.name   = "scroll";
				this.scroll.parent = this;

				this.scroll.initialize(this, 1, this.maxIndex+1, 1);
				this.scroll.attachToObject();
				this.scroll.resizeScroller(this.listHeight);
				this.scroll.x = this.listWidth + 5;
				this.scroll.y  = 0;
				this.scroll.depth = -100;
				this.scrollTo = scroll_to;
				this.scroll.visible = true;
			}
		}
		this.updateList();
		if(!this.markCurrent && !this.releaseCallbackObject){
			listArea.enabled = false;
		}
		this.visible = true;
	}

	function hideObject(){
		if(this.scroll){
			this.scroll.parent = null;
			this.scroll = null;
		}
		this.visible = false;
	}

	function scroll_to(scrollPos){
		this.topIndex = scrollPos;
		this.updateList();
	}

	// функция прячет все элементы в звданном интервале
	function hideItemsInInterval(startItem, endItem){
		if(startItem != undefined && endItem != undefined && endItem >= startItem){
			for(var i = startItem; i <= endItem; i++){
				this.listItems[i].hideItem();
			}
		}
	}

	// функция вычисляет суммарную высоту всех элементов списка
	function calculateTotalItemsHeight(){
		var curHeight = 0;
		for(var i = 0; i < this.listItems.length; i++){
			curHeight += this.listItems[i].itemHeight;
			curHeight += this.lineInterval;
		}
		curHeight -= this.lineInterval;
		this.itemsTotalHeight = curHeight;
//trace("itemsTotalHeight == " + this.itemsTotalHeight);
	}

	// функция вычисляет номер верхнего элемента 
	// при полностью проскроллированном вниз списке
	function calculateMaxIndex(){
		var curHeight = 0;
		for(var i = this.listItems.length - 1; i >= 0; i--){
//trace("testing item: " + i);
			if(curHeight + this.listItems[i].itemHeight > this.listHeight){
				// выйдем - значит спрятать все остальные (индекс которых больше или равен)
				this.maxIndex = i + 1;
//trace("maxIndex == " + this.maxIndex);
				break;
			} else {
				curHeight += this.listItems[i].itemHeight;
				curHeight += this.lineInterval;
			}
		}
	}

	function listRollover(){
		listArea.onMouseMove = this.mouseMoveHandler;
		//listArea.onRelease = releaseHandler;
		listArea.onRelease = releaseHandlerAlias;
	}

	function listRollout(){
		this.currentItemMarker.visible = false;
		listArea.onMouseMove = null;
	}

// ====================== !!!!!!!!!!!!!!!!!!!!!!!!!
// алиас нужен для того чтобы 
// не было ошибок с областью видимости переменных
	function mouseMoveHandlerAlias(){
		mouseMoveHandler();
	}
// ======================= !!!!!!!!!!!!!!!!!!!!!!!!!

	function mouseMoveHandler(){
//trace("mouseMove" + Player._time);
		var curY = yMouse;
		for(var i = 0; i < screenItemsParams.length; i++){
			if(curY > screenItemsParams[i][1]
				&& curY < screenItemsParams[i][1] + screenItemsParams[i][2]){
				if(markCurrent)
					markCurrentItem(i);
				return;
			} else {
				currentItemMarker.visible = false;
			}
		}
	}

// =========================== !!!!!!!!!!!!!!!!!!!!!!!!!
// алиас нужен для того чтобы 
// не было ошибок с областью видимости переменных
	function releaseHandlerAlias(){
		releaseHandler();
	}
	// =========================== !!!!!!!!!!!!!!!!!!!!!!!!!

	function releaseHandler(){
		if(this.releaseCallbackObject !=undefined && this.releaseCallbackFunction !=undefined ){
			var curY = yMouse;
			for(var i = 0; i < this.screenItemsParams.length; i++){
				if(curY > this.screenItemsParams[i][1]
					&& curY < this.screenItemsParams[i][1] + this.screenItemsParams[i][2]){
					if(this.markSelected){
						this.markSeletedItem(i + this.topIndex);
					}
					this.releaseCallbackFunction.call(this.releaseCallbackObject, this.screenItemsParams[i][0]);
					return;
				}
			}
		}
	}

	// подсвечивает выбранный элемент списка
	function markSeletedItem(targetItem){
		if(targetItem - this.topIndex >= 0
			&&  targetItem - this.topIndex < this.screenItemsParams.length){
			this.lastSelectedItem = targetItem;
//			this.selectedItemMarker.x = -4;
			this.selectedItemMarker.y = this.screenItemsParams[targetItem - this.topIndex][1] - 2;
			this.selectedItemMarker.height =
				this.screenItemsParams[targetItem - this.topIndex][2] + 4;
			this.selectedItemMarker.visible = true;
		} else {
			this.selectedItemMarker.visible = false;
		}
	}

	// подсвечивает текущий (под курсором) элемент списка
	function markCurrentItem(targetItem){
//		this.currentItemMarker.x = -4;
		this.currentItemMarker.y = this.screenItemsParams[targetItem][1] - 2;
		this.currentItemMarker.height = this.screenItemsParams[targetItem][2] + 4;
		this.currentItemMarker.visible = true;
	}

	// устанвливает цвет фона для конкретной строчки
	function setItemBgColor(itemId, bgColor){
		this.listItems[itemId].setBgColor(bgColor);
	}

	function setReleaseCallback(targetObject, targetFunction){
		this.releaseCallbackObject = targetObject;
		this.releaseCallbackFunction = targetFunction;
	}

	function scrollList(itemsCount){
		if(itemsCount > 0){
//trace("Item count > 0");
			// скроллируем вниз
			if(this.bottomIndex > 0){
				if(itemsCount >= this.bottomIndex){
					this.topIndex += this.bottomIndex;
					this.updateList();
				}else {
					this.topIndex += itemsCount;
					this.updateList();
				}
			}
		} else if(itemsCount < 0){
//trace("Item count < 0");
			// скроллируем вверх (возвращаемся в начало)
			if(this.topIndex > 0){
				if(itemsCount <= -this.topIndex){
					this.topIndex = 0;
					this.updateList();
				}else {
					this.topIndex += itemsCount;
					this.updateList();
				}
			}
		}
	}	

	function getItemsTotal(){
		return this.listItems.length;
	}

	function getItemHeight(itemNumber){
		if(itemNumber >= 0 && itemNumber < this.listItems.length){
			return this.listItems[itemNumber].itemHeight;
		}
		return 0;
	}
]]></script>
</composition>
</rmml>