//NU!!! ESTE TESTAT COMPLET !!!!
//NU!!! ESTE TESTAT COMPLET !!!!
//NU!!! ESTE TESTAT COMPLET !!!!
//NU!!! ESTE TESTAT COMPLET !!!!

var sortedObject = null;
var MultiArray = Class.create();
MultiArray.prototype = {

  lines : new Array(),
  order : new Array(),
  colName : new Array(),
  nrCol : 0,
  isType : /^(string|date|datetime|number)$/,
  colType : new Array(),
  sortPriority: new Array(),
  sortMode: new Array(),
  defaultSortPriority: new Array(),
  defaultSortMode: new Array(),
  visibility: new Array(),
  idTable: -1,

  initialize: function(idTable)
  {
	this.clear();
	this.genElemFromTable(idTable);
	this.idTable = idTable;
  },

  each: function(iterator)
  {
    for (var i = 0; i < this.length; i++)
        for (var j=0; j < this.nrCol; j++)
            iterator(this.lines[i][j],i,j);
  },

  clear: function()
  {
    this.lines = new Array();
    this.nrCol = 0;
    this.colType = new Array();
    this.order = new Array();
    this.defaultSortPriority = new Array();
    this.sortPriority = new Array();
    this.sortMode = new Array();
    this.defaultSortMode = new Array();
  },

  firstLine: function()
  {
    return this.lines[0];
  },

  lastLine: function() {
    return this.lines[this.lines.length - 1];
  },

  firstLineElem: function(line)
  {
    return this.lines[line][0];
  },

  lastLineElem: function(line)
  {
    return this.lines[line][this.lines[line].length-1];
  },

  getLine: function(line)
  {
  	return this.lines[line];
  },

  getColumn: function(nrCol)
  {
  	if ((nrCol < 0) || (nrCol > this.nrCol))
  		return null;
  	col = new Array();
	for (var i=0;i<this.lines.length;i++)
		col[i] = this.lines[i][order[nrCol]];
	return col;
  },

  getColumnByName : function(name)
  {
	var i = this.getColumnPosition(name);
	if (i<0) return null;
    return this.getColumn(i);
  },

  getColumnPosition : function(name)
  {
  	for (var i=0;i<this.nrCol;i++)
		if (this.colName[i].toLowerCase() == name.toLowerCase())
			return i;
	return -1;
  },

  setColumnsType : function(iterable)
  {
  	cT = $A(iterable);
  	if (cT.length != this.nrCol)
  		return 10;
  	for (var i=0;i<cT.length;i++)
  	{
		var match = cT[i].serch(this.isType);
		if (match < 0) return 1;
  	}
  	this.colType = cT;
  	return 0;
  },

  setColumnType : function(type, pos)
  {
  	if (typeof type != 'string')
  		return 1;
	if (type.search(this.isType) < 0)
		return 2;
  	if ((pos < 0) || (pos > this.nrCol-1))
  		return 10;

	this.colType[this.order[pos]] = type;
	return 0;
  },

  setColumnsName : function(iterable)
  {
  	cN = $A(iterable);
  	if (cN.length != this.nrCol)
  		return 10;
  	this.colName = cN;
  	return 0;
  },

  setColumnName : function(name, pos)
  {
  	if ((pos < 0) || (pos > this.nrCol-1))
  		return 10;
  	this.colName[this.order[pos]] = name;
  	return true;
  },

  setColumnsVisibility : function(iterable)
  {
  	cN = $A(iterable);
  	if (cN.length != this.nrCol)
  		return 10;
  	this.visibility = cN;
  	return 0;
  },

  setColumnVisibility : function(name, pos)
  {
  	if ((pos < 0) || (pos > this.nrCol-1))
  		return 10;
  	this.visibility[this.order[pos]] = name;
  	return true;
  },

  setDefaultSort: function(sortPriority, sortMode)
  {
  	sP = $A(sortPriority);
  	sM = $A(sortMode);
  	if (sP.length != sM.length)
  	{
		return 10;
	}
	this.defaultSortPriority = sP;
	this.defaultSortMode = sM;
	return 0;
  },

  deleteLine : function(pos)
  {
  	if ((pos < 0) || (pos > this.lines.length))
  		return 10;
  	for (var i=pos;i<this.lines.length-1;i++)
  		this.lines[i] = this.lines[i+1];
  	this.lines.length--;
  },

  addLine: function (iterable)
  {//PENTRU AJAX DE VAZUT BEHAVIOR -- FUNCTIE INCOMPLETA !!!(SINCRONIZARE CU TABELA)
  	line = $A(iterable);
  	if (line.length != this.nrCol)
		return 10;
    this.lines[this.lines.length] = line;
    return true
  },

  addLinePosition : function(iterable, pos)
  {
	for (var i=this.lines.length;i>pos;i--)
		this.lines[i] = this.lines[i-1];
	this.lines[pos] = $A(iterable);
  },

  addColumn: function (iterable, name, type)
  {//PENTRU AJAX DE VAZUT BEHAVIOR -- FUNCTIE INCOMPLETA !!!(SINCRONIZARE CU TABELA)
  	var test;
	if ((test = type.search(this.isType)) != 0)
		return test;

	var col = $A(iterable);
	if (col.length != this.lines.length)
		return 10;
	for (var i=0;i<this.lines.length;i++)
		this.lines[i][this.nrCol] = col[i];

	this.order[this.nrCol] = this.nrCol;
	this.nrCol++;
	this.setColumnType(type, this.nrCol-1);
	this.setColumnName(name, this.nrCol-1);
	return 0;
  },

  addColumnPosition: function(iterable, pos, name, type)
  {
  	var test = this.addColumn(iterable, name, type);
	if (test != 0)
		return test;
	this.changeColumnPosition(this.nrCol-1, pos);
	return 0;
  },

  changeColumnPosition :function (oldPos, newPos)
  {//de sincronizat cu tabela !!!
  	if ((oldPos < 0) || (oldPos > this.nrCol-1))
  		return 10;
  	if ((newPos < 0) || (newPos > this.nrCol-1))
  		return 10;

	var auxOrder = this.order[oldPos];
	if (oldPos > newPos)
	{
		for (var i=oldPos;i>newPos;i--)
			this.order[i] = this.order[i-1];
	}
	else
	if (oldPos < newPos)
	{
		for (var i=oldPos;i<newPos;i++)
			this.order[i] = this.order[i+1];
	}
	this.order[newPos] = auxOrder;
	return 0;
  },

  genElemFromTable : function(idTable)
  {
	this.clear();

  	objTable = document.getElementById(idTable);
	if (objTable == null)
		return 11;
  	objTable.multipleArray = this;
    objHead = objTable.tHead;
    listaTh = objHead.getElementsByTagName('th');
	for (var i=0;i<listaTh.length;i++)
	{
		if (Element.hasClassName(listaTh[i], 'invisible'))
			this.visibility[i]= 1;
		else this.visibility[i] = 0;

        var objDiv = listaTh[i].getElementsByTagName('div')[0];
		if (typeof objDiv != 'undefined')
		{
			spanName = objDiv.getElementsByTagName('span')[0];
			this.colName[i] = spanName.innerHTML;
		}
		else
		{
			this.colName[i] = listaTh[i].innerHTML;
		}
	}
	for (var i=0;i<objTable.rows.length;i++)
	{
		objRowCells = objTable.rows[i].cells;
		this.lines[i] = new Array();
		for (var j=0;j<objRowCells.length;j++)
		{
			this.lines[i][j] = objRowCells[j].innerHTML;
		}
		this.order[i] = i;
		this.colType[i] = 'string';
	}
	 if (objTable.cols) this.nrCol = objTable.cols
	 else
	 {
	 	this.nrCol = objTable.rows[0].cells.length;
	 }
	 return 0;
  },

  refreshTable : function()
  { //atentie !!! numarul de element din table TREBUIE sa fie egal cu cel din MA
  	objTable = document.getElementById(this.idTable);
	if (objTable == null)
		return 11;

 	if (objTable.cols) 
		if (objTable.nrCol != this.nrCol)
			return 10;
 	else
	{
		if (this.nrCol != objTable.rows[0].cells.length)
			return 10;
	}

    listaTh = objHead.getElementsByTagName('th');
	for (var i=0;i<listaTh.length;i++)
	{
		var objDiv = listaTh[i].getElementsByTagName('div')[0];
		if (typeof objDiv != 'undefined')
		{
			spanName = objDiv.getElementsByTagName('span')[0];
			spanArrow = objDiv.getElementsByTagName('span')[1];
			spanName.innerHTML = this.colName[this.order[i]];

			var pos = -1;
			for (var j=0;j<this.sortPriority.length-this.defaultSortPriority.length;j++)
				if (this.sortPriority[j]==i) pos = j;
			if (pos == -1)
				spanArrow.innerHTML ="&nbsp;&nbsp;&nbsp;";
			else
				if (this.sortMode[pos] == -1) spanArrow.innerHTML = "&nbsp;&nbsp;<img src='images/down.gif'>";
				else spanArrow.innerHTML = "&nbsp;&nbsp;<img src='images/up.gif'>";
		}
	}

	for (var i=0;i<objTable.rows.length;i++)
	{
		var objRowCells = objTable.rows[i].cells;
		for (var j=0;j<objRowCells.length;j++)
		{
			objRowCells[j].innerHTML = this.lines[i][this.order[j]];
		}
	}
  },

  writeDataToTable : function(idTable)
  {//deprecated  (pierde behaviorul!)
  	objTable = document.getElementById(idTable);
	if (objTable == null)
		return 11;

	objHead = document.createElement('thead');
  	for (var i=0;i<this.nrCol;i++)
  	{
		objTh = document.createElement('th');
		objTh.innerHTML = this.colName[this.order[i]];
		if (this.visibility[this.order[i]] == 1)
			Element.addClassName(objTh,'invisible');
		objHead.appendChild(objTh);
	}
	objBody = document.createElement('tbody');
	for (i=0;i<this.lines.length;i++)
	{
		objTr = document.createElement('tr');
		objTr.id = idTable+'_tr_'+i;
		for (var j=0;j<this.nrCol;j++)
		{
			objTd = document.createElement('td');
			if (this.visibility[this.order[j]] == 1)
				Element.addClassName(objTd,'invisible');

			objTd.innerHTML = this.lines[i][this.order[j]];
			objTr.appendChild(objTd);
		}
		objBody.appendChild(objTr);
	}
   	objTable.innerHTML = "";
	objTable.appendChild(objHead);
	objTable.appendChild(objBody);
  	objTable.className = 'grid';
  	//Behaviour.apply();
	return 0;
  },

  compareFunction : function(la, lb)
  {
  	for (var p=0;p<sortedObject.sortPriority.length;p++)
  	{
	  var col = sortedObject.sortPriority[p];
	  var sm = sortedObject.sortMode[p];
	  switch(sortedObject.colType[col])
	  {
		  case 'number':
	  	  {
		  	if ((la[col]-lb[col]) != 0) return (la[col]-lb[col])*sm;
		  }
		  break;
		  case 'string' :
		  {
		  	if (la[col].toLowerCase()<lb[col].toLowerCase()) return -1*sm;
		  	if (la[col].toLowerCase()>lb[col].toLowerCase()) return 1*sm;
		  }
		  break;
		  case 'date' : //format obligatoriu dd/mm/yyyy
		  {
		  	laDate = new Date();
		  	lbDate = new Date();
		  	var tar = la[col].split('/');
			laDate.setFullYear(parseInt(tar[2],10),parseInt(tar[1],10)-1,parseInt(tar[0],10));
			var tar = lb[col].split('/');
            lbDate.setFullYear(parseInt(tar[2],10),parseInt(tar[1],10)-1,parseInt(tar[0],10));
            if (laDate < lbDate) return -1*sm;
            if (laDate > lbDate) return 1*sm;
		  }
		  break;
		  case 'datetime' : //format obligatoriu dd/mm/yyyy hh24:mi:ss
		  {
		  	laDate = new Date();
		  	lbDate = new Date();
			var dh = la[col].split(' ');
		  	var tar = dh[0].split('/');
			laDate.setFullYear(parseInt(tar[2],10),parseInt(tar[1],10)-1,parseInt(tar[0],10));
			tar = dh[1].split(':');
			laDate.setHours(parseInt(tar[0],10),parseInt(tar[1],10),parseInt(tar[2],10));

			dh = lb[col].split(' ');
		  	tar = dh[0].split('/');
			lbDate.setFullYear(parseInt(tar[2],10),parseInt(tar[1],10)-1,parseInt(tar[0],10));
			tar = dh[1].split(':');
			lbDate.setHours(parseInt(tar[0],10),parseInt(tar[1],10),parseInt(tar[2],10));

            if (laDate < lbDate) return -1*sm;
            if (laDate > lbDate) return 1*sm;
		  }
		  break;
		  default:
		  {
		  	return 0;
		  }
	  }
	}
  	return 0;
  },

  sort: function (sortPriority, sortMode)
  {
  	sortedObject = this;
  	this.sortMode = $A(sortMode);
  	this.sortPriority = $A(sortPriority);
  	if (this.sortMode.length != this.sortPriority.length)
  	{
		this.sortMode = new Array();
		for (var i=0;i<this.sortPriority.length;i++)
			this.sortMode[i] = 1;
	}
	this.sortMode = this.sortMode.concat(this.defaultSortMode);
	this.sortPriority = this.sortPriority.concat(this.defaultSortPriority);
	this.lines.sort(this.compareFunction);
	sortedObject = null;
	return 0;
  },

  sortByName: function(sortNamePriority, sortMode)
  {
	var sP = new Array();
	var sNP = $A(sortNamePriority);
	for (var i=0;i<sNP.length;i++)
	{
		sP[i] = this.getColumnPosition(sNP[i])
		if (sP[i] < 0) return 20;
	}

    return this.sort(sP, sortMode);
  }
};


var $MA = function(idTable)
{
  var multiArray = new MultiArray(idTable);
  return multiArray;
}
