/**
    @ver 1.1
    @author coco
*/
var FMTable=(function(){
    var last=new Array();
    var template= new Array();
    function constructor(){
       
    }
    function _processId(objContext){
        //TODO :: cache this response
        var idTable=_getTableIdByContext(objContext);
        var id=objContext.id;
        id=id.replace(FormManager.getFormName()+"_","")
        id=id.replace(idTable+".","");        
        id=id.replace(idTable+"_","");     
		var idAr=id.split("@");
        return idAr[0];
        
    }
    function _processIdByString(id,idTable){
        id=id.replace(FormManager.getFormName()+"_","");        
        id=id.replace(idTable+".","");        
        id=id.replace(idTable+"_","");        
        return id;
    }

    /*
    */
    function _getTableByContext(objContext){
        try{
            if (objContext.tagName=="TABLE") return objContext;
            return Core.detectParent(objContext,"TABLE");
        }catch(e){
            Error.dumpObject(e) ;
        }


    }

    function _getTableIdByContext(objContext, original){
    	var objTable=_getTableByContext(objContext);
        if (!original) {
            //alert("filter "+filter+"::"+FormManager.processId(objTable));
            return FormManager.processId(objTable);
        }
        else return objTable.id;
    }

    function _getTemplateByContext(objContext){
        //TODO: check if objContext is the template.
        var tableId=_getTableIdByContext(objContext,false)
        var objTemplateId=FormManager.getFormName()+"_"+tableId+"_"+"template";
        var objTemplate=document.getElementById(objTemplateId);
        return objTemplate;
    }

    function _getTemplateByTableId(tableId){
        var objTemplateId=FormManager.getFormName()+"_"+tableId+"_"+"template";
        var objTemplate=document.getElementById(objTemplateId);
        return objTemplate
    }

    function _copyEvents(objSrc, objDest){
        for (var localIndex in objSrc)
        {
            var value=localIndex;
            if (value.substr(0,2)=="on")
            {
                objDest[localIndex]=objSrc[localIndex] ;
            }
        }
        objDest.id=objSrc.id;
        objDest.name=objSrc.name;
    }
    function _getLineId(objContext)
	{
        var obj;
        if (objContext.tagName=="TR") obj=objContext;        
        else obj=Core.detectParent(objContext,"TR");
        var id=_processId(obj);
//        alert(id);
        return id;
    }

    function _sMerge(){
		var out= new Array();
		returnObject=arguments[0];
        for(var i=1;i<arguments.length;i++)
		{
            var arg=arguments[i]
            for(var index in arg) {
                var cObj= arg[index];
                if (cObj&&cObj.tagName)
                {
                        var id=_processId(cObj);
                        if (!id){
                            alert("error :"+cObj.tagName);
                            Error.dumpObject(cObj,1);                                    
                        }
                        if (returnObject) out[id]=cObj;
                        else out[id]=cObj.value;
                }                
                 ;	
            }
		}

		return out;
	}
    function _toArrayLine(objLine){
        var out=new Array();
        if (objLine.tagName=="TR")
        {
			
			/*
			var lineObjects=_sMerge(true,
                                objLine.getElementsByTagName('select')
                                ,objLine.getElementsByTagName('input')
                                ,objLine.getElementsByTagName('textarea')
                                ,objLine.getElementsByTagName('label')
                            );
           
            */
			var lineObjects= new Array();
			_parseElement(objLine,lineObjects,new Array({"SELECT":1,"INPUT":1,"TEXTAREA":1,"LABEL":1}));
			//Error.dumpObject(lineObjects,1);
			
			return lineObjects;
        }
        return null;
    }
	function _parseElement(obj,out,elements){
	    if (obj.hasChildNodes()){
		    var list=obj.childNodes;
			var n=list.length;
			for(var i=0;i<n;i++){
			    var lObj=list.item(i);
			    var tag=lObj.tagName;
			    
				if (elements[0][tag]){
					out[_processId(lObj)]=lObj;
				}
				_parseElement(lObj,out,elements);
			}
		    
		}
	} 
	function _getTRItemsById(tableId){
	    var objId=FormManager.getFormName()+"_"+tableId;
	    var obj=document.getElementById(objId);
	    var out=_getTRItemsByContext(obj);
	    return out;
	}
    function _getTRItemsByContext(objContext,onlyInputs){
        var objTemplate=_getTemplateByContext(objContext);
        var obj=Core.detectParent(objTemplate,"TBODY");
        var out= new Array();
        var nLines=obj.childNodes.length;
//      alert (nLines);
        for(var indexLine =0; indexLine<nLines;indexLine++)
        {
			var objLine=obj.childNodes[indexLine];
            if (objLine.tagName=="TR")
            {
                //if is hidden then is deleted
                if (objLine.style.dispay=='none') continue;
				if (!onlyInputs){
                    out[out.length]=objLine;
                }
                else{
                    //TODO DO
					var rowId=_getLineId(objLine);
                    out[rowId]=_toArrayLine(objLine)                    
                }
                
                
            }
        }
//        Error.dumpObject(out,2)
        return out;
    }

    
    function _getNewTRId (objTemplate,useLast){

        var tableId=_getTableIdByContext(objTemplate);
        if(useLast){
            var id =FormManager.getFormName()+"."+tableId;
            mId=Type.toInt(last[id])+1;
            last[id]=mId;
                      
            
        } else{
            
            var items=_getTRItemsByContext(objTemplate)
            //alert(newObj);
            var mId=0;
            var i=0;
            var id=10;
            for(var index in items)
            {
                //alert(id+"::"+i);
                var obj=items[index];
                if (Type.isObject(obj))
                {
                    var id=Math.abs(_processId(obj));
                    if (id>mId) mId=id;
                }
    
            }
            mId++;
            last[id]=mId;
             
        }
        //alert(mId+":"+tableId);
        return FormManager.getFormName()+"_"+tableId+"."+mId;
    }

    constructor.getTemplateByTableId=function(tableId)
            {
                return _getTemplateByTableId(tableId)
            }

    constructor.getTemplateByContext=function(objContext)
            {
                return _getTemplateByContext(objContext);
            }

    constructor.copyEvents=function(objSrc, objDest)
            {
                _copyEvents(objSrc,objDest);
            }

    constructor.duplicateById=function(tableId,executeEvents,useLast)
            {
                var objTemplate=_getTemplateByTableId(tableId);
                this.duplicateByContext(objTemplate,executeEvents,useLast);
            }


    constructor.addRow=function(objContext)
            {
				return this.duplicateByContext(objContext);
            }
    
    constructor.getTableIdByContext=function(objContext)
    		{
			    return _getTableIdByContext(objContext);
			}
			
	constructor.duplicateByContext=function(objContext,doNotExecuteEvents,useLast)
            {
                
				var objTable=_getTableByContext(objContext);
				var objTemplate=_getTemplateByContext(objContext);
				if (!objTemplate) {
				 	alert("objTemplate is null");
				    throw "objTemplate is null";
				}
                var idRow=_getNewTRId(objTemplate,useLast);
                if (objTable.onBeforeDuplicate)
                {
                    objTable.onBeforeDuplicate(objContext, idRow)
                }

                var parent=objTemplate.parentNode;
//                var newObj=objTemplate.cloneNode(true);  
                var noRow=_processIdByString(idRow,_getTableIdByContext(objTable));
                var newObj=FormManager.cloneNode(objTemplate,function(src,dest){
                    if (src.name) dest.name=src.name.replace("[-1]","["+noRow+"]");
                    if (src.id){
                        dest.id=src.id.replace("-1",noRow);
                        dest.id=dest.id.replace("-1",noRow);
                    } 
                });                                             
                parent.appendChild(newObj);                
                newObj.setAttribute("style","");
                newObj.style.display="";
                newObj.id=noRow;

                if ((!doNotExecuteEvents)&&(objTable.onEndDuplicate)){
                    objTable.onEndDuplicate(objContext, newObj)
                }
                return newObj;
            }

    constructor.populateLine=function(objLine,data)
            {
            if (objLine.tagName=="TR")
            {
                var objs=this.toArrayLine(objLine,true);
//                Error.dumpObject(objs,1);
//                alert(typeof(objs));
                for(var index in objs)
                {
//                    var index=_processId(obj);
//                    alert(index);
                    if ((data)&&(data[index])) //populate
                    {
                        var value=data[index];
                        var obj=objs[index];
                        var tag=obj.tagName
                        switch (tag)
                        {
                            case "INPUT": 
                                obj.value=value;
                                break;
                            case "LABEL":
                            case "TEXTAREA":
                                obj.innerHTML=value;
                                break;
                            case "SELECT":
                                var n=obj.options.length;
                                for(i=0;i<n;i++) obj.options[i].selected=false;
                                for(i=0;i<n;i++) if (obj.options[i].value==value){obj.options[i].selected=true;break;}
                                break;
                            default:
                        }
                    }
                  
                
                }
            }
        }
    
    /*
        @descr: in esenta sterge obiectele de dupa cel de referinta si apoi le pune inapoi  
    */
    constructor.insertAfter=function(objContext)
        {
            var objTable=_getTableByContext(objContext);
            var tableId=_getTableIdByContext(objTable);
            var objTemplate=_getTemplateByContext(objContext);
            var parent=objTemplate.parentNode;
            var idRow=_getNewTRId(objTemplate);
            //begin creare obiect nou
            var noRow=_processIdByString(idRow,_getTableIdByContext(objTable));
            var newObj=FormManager.cloneNode(objTemplate,function(src,dest){
                if (src.name) dest.name=src.name.replace("[-1]","["+noRow+"]");
                if (src.id){
                    dest.id=src.id.replace("-1",noRow);
                } 
            });                                             
            //end create obiect nou
       
            //copiaza ultimele obiecte pana la cel de referinta
            var objRefContext=Core.detectParent(objContext,"TR");
            var idRegContext=objRefContext.id;
            var objTBody = Core.detectParent(objRefContext,"TBODY");
            var objects= new Array();
            var n=objTBody.childNodes.length;
            var copy=true;
            //merge inapoi, le salveaza si apoi le sterge
            for(var i=n-1;i>=0;i--)
            {
                var obj=objTBody.childNodes[i];
                var id=obj.id;
                if (id==idRegContext)
                {
                    break;
                }
                else
                {
                    objects[objects.length]=obj;
                    obj.parentNode.removeChild(obj);
                }
            }
            //acum le punem inapoi incepand cu cel duplicat.
            newObj.setAttribute("style","");
            newObj.style.display="";
            newObj.id=idRow;
            objTBody.appendChild(newObj);
            
    
           for(var i=objects.length-1;i>=0;i--)
            {
                objTBody.appendChild(objects[i]);
            }
    
            //renumerotare
            var items=_getTRItemsByContext(objTemplate);
            i=0;
            for(var index in items)
            {
                var id=_processId(items[index]);
                if (id=="template") continue;
                i++;
//                items[index].id=FormManager.getFormName()+"_"+tableId+"."+i;
//				items[i].id=FormManager.getFormName()+"_"+tableId+"."+i;
                items[index].id=tableId+"."+i;
				items[i].id=tableId+"."+i;

            }
    
    
            if (objTable.onEndInsertAfter)
            {
                //sursa & destinatie
                objTable.onEndInsertAfter(objRefContext,newObj)
            }        
        }
    
    constructor.deleteRow=function(obj,deleteLogical)
        {
            var objTable=_getTableByContext(obj);
            var cont=true;
            var objTR=Core.detectParent(obj,"TR");
            if (objTable.onBeginDeleteRow){
                cont=objTable.onBeginDeleteRow(objTR);            
            }

            if (cont){
				//setergerea se face logic, adica se pune un flag pe 1
                if (deleteLogical){
					var array=_toArrayLine(objTR);
					if (array["isDeleted"]){
						//alert("setting is Deleted");
						array["isDeleted"].value=1;
					}
					objTR.style.display="none";				    
				}else{
	                objTR.parentNode.removeChild(objTR);
                }
                if (objTable.onEndDeleteRow){
                    objTable.onEndDeleteRow(obj);            
                }
            }

            
        }
            

    constructor.getLineId=function(objContext)
	{
        var obj;
        if (objContext.tagName=="TR") obj=objContext;        
        else obj=Core.detectParent(objContext,"TR");
        var id=_processId(obj);
//        alert(id);
        return id;
    }
    

    constructor.processId=function(objContext)
            {
                return _processId(objContext);
            }

    constructor.sMerge=function() {
		var out= new Array();
		returnObject=arguments[0];
        for(var i=1;i<arguments.length;i++)
		{
            var arg=arguments[i]
            for(var index in arg) {
                var cObj= arg[index];
                if (cObj&&cObj.tagName)
                {
                        var id=_processId(cObj);
                        if (!id){
                            alert("error :"+cObj.tagName);
                            Error.dumpObject(cObj,1);                                    
                        }
                        if (returnObject) out[id]=cObj;
                        else out[id]=cObj.value;
                }                
                 ;	
            }
		}

		return out;
	}
    constructor.toArrayLineByContext=function(objContext)
            {
                var objTR=Core.detectParent(objContext,"TR");
                return this.toArrayLine(objTR);    
            }

    constructor.toArrayLine=function(objLine,returnObject)
            {
                return _toArrayLine(objLine);            
/*                    for(var index in lineObjects)
                    {
                        
                        var cObj=lineObjects[index];
                        if (cObj&&cObj.tagName)
                        {
                                var id=_processId(cObj);
                                if (!id){
                                    alert("error :"+cObj.tagName);
                                    Error.dumpObject(cObj,1);                                    
                                }
                                if (returnObject) out[id]=cObj;
                                else out[id]=cObj.value;
                        }
                    }
                }
                return out;
*/
  
            }
    
    constructor.toArrayByContext=function(objContext,returnObject)
            {
                return _getTRItemsByContext(objContext,true);
            }
    
    constructor.toArrayByTableId=function(tableId,returnObject)
            {
                var objTemplate=_getTemplateByTableId(tableId);
                return this.toArrayByContext(objTemplate,returnObject);
            }
    constructor.toTRArrayByTableId=function(tableId)
    		{
			    var out= _getTRItemsById(tableId);
			    return out;
			}
    constructor.getTRItemsByContext=function(objContext)
            {
                return _getTRItemsByContext(objContext);
            }

    /*
        @param data: base64, unserialize -> import from php
    */
    constructor.populateByContext=function(objContext,dataEncoded)
            {
                var objTable=_getTableByContext(objContext);
                var data=XString.unserialize(XBase64.decode(dataEncoded));
                while(data.length>0)
                {
                    var cData=data.shift();
                    if(!cData) continue;
					var objLine=FMTable.duplicateByContext(objContext,true,true);
                    if (objTable.onBeginPopulate) objTable.onBeginPopulate(objContext,objLine);
					this.populateLine(objLine,cData);
                    if (objTable.onEndPopulate) objTable.onEndPopulate(objContext,objLine);
                }
            }
                
    return constructor;   
})();