
/************************************************************************
*************************************************************************
		Dynamic Table
*************************************************************************
************************************************************************
*Requiere 
*-jquery.js
*-jquery-ui.js
*-jquery.validate.js
*
*Idealmente
*-bootstrap.css
*************************************************************************/

(function ( $ ) {


 $.dynTable = function(element, options) {
 	var defaults = {
            id : null,
            url: "",
            prefix : "",
            colModel : null,
            root: null,
            local : false,
            items : [],
            origItems : [],
            dyn : false,
            expand :  { "exp":false, "column":"" , "attribute": "", "classOpenIcon":"fa-minus", "classCloseIcon":"fa-plus" },
            edit : false,
            lazyInit : false,
            dateFormatIn:"dd/mm/yy",
            dateFormatOut:"dd/mm/yy",
            ajaxData : {}
        };

        var s = this;
        s.settings = {};

        //CONSTRUCTOR
        s.construct = function() {
            s.settings = $.extend(true,{}, defaults, options);
            s.settings.id = (typeof element.attr('id') != 'undefined')? element.attr('id') : element.attr('class');
            if(s.settings.lazyInit == false ){
            	s.init();
            }
        };
        
        //PUBLIC METHODS
        
        s.init = function (){
        	if(s.settings.items != null && typeof s.settings.items != 'undefined' &&    s.settings.items.length != 0  ){
            	s.settings.origItems = s.settings.items.slice();
                s.paint();
            }else if(s.settings.url != null && s.settings.local == false){
            	s.loadAjax();
            }
            else
            {
            	s.settings.items = [];
            	s.settings.origItems = [];
            	s.paint();
            }
        }
        
        s.paint = function(){
            var t = $('#'+s.settings.id);
            t.html("");
            var r = "<table ";
            r+= " id='dynTable"+s.settings.id+"' ";
            r+="  class='dlaTable'>";
            r+=_paintHeader();
            r+= _paintBody();
            r+="</table>";
            t.append(r);
            
            _loadStyleFunctions();
            if(_isDynamic())
        	{
            	$("#"+s.settings.id+"AddButton").click( $.proxy(s.addRow,s)  );
        	}
            
        };
        
        s.paintError = function(error){
            $('#'+s.settings.id).html( "<h4 class='text-danger'  >"+error+"</h4>" );
        };

        s.getItem = function(index){
            return items[index];
        };
        
        
        s.addRow = function(item){
        	if(typeof item === 'undefined' )
        	{
        		item = {};
        	}
            s.settings.items.push(item); 
        	var r =_paintRow(item, s.settings.items.length -1);
        	$("#dynTable"+s.settings.id+" tr").last().after(r);
        	_loadStyleFunctions();
        };
        
        s.dellRow = function(rowid){
        	$(".dynTr"+s.settings.id+rowid).remove();
        }
        
        s.openHideKids = function(row){
	        var index = $(row).attr("index");
	        if($(row).hasClass("dynOpenTR")){
		   	    $(".dynTrParent"+s.settings.id+index).hide();
		   	    $(row).removeClass("dynOpenTR");
		   	    $(".dynTrIco"+s.settings.id+index).removeClass("fa-minus");
		   	    $(".dynTrIco"+s.settings.id+index).addClass("fa-plus");
	        }
	        else
	        {
		   	  $(".dynTrParent"+s.settings.id+index).show();
		   	  $(row).addClass("dynOpenTR");
		   	  $(".dynTrIco"+s.settings.id+index).removeClass("fa-plus");
		   	  $(".dynTrIco"+s.settings.id+index).addClass("fa-minus");
	        }
        }
        
        s.reset = function ()
        {
        	s.settings.items = s.settings.origItems.slice();
        	s.paint();
        }
        
        s.eraseTabel = function ()
        {
        	var t = $('#'+s.settings.id);
            t.html("");
        }
        
        s.loadAjax = function ()
        {
        	$.ajax({
                url : s.settings.url,
                type : 'post',
                data : s.settings.ajaxData,
                dataType : 'json',
                success : function(data){
                	s.settings.items = ( s.settings.root != null  )?  _deepFind(data,s.settings.root )   : data ;
                	s.settings.origItems = s.settings.items.slice();
                	s.paint();                      
                },
                'error' : function(jqXHR,textStatus,errorThrown){
                    s.paintError(textStatus);
                }
            });
        }
        
        var _isDynamic = function(){
        	return s.settings.dyn == true && s.settings.edit == true ;
        }
        
        s.getItems = function ()
        {
        	return s.settings.items;
        }
        
        s.setItems = function (items)
        {
        	return s.settings.items = items;
        }
        
        
        s.changeDateFormat = function (formatIn,formatOut,value)
        {
        	var _value = value;
        	if(value != null  && value != "" && typeof value != 'undefined'){
	        	_value = value.split("T")[0]
				var d = $.datepicker.parseDate( formatIn, _value ); 
				
				d = new Date(d.valueOf() + d.getTimezoneOffset() * 60000);
				_value = $.datepicker.formatDate(formatOut,d);
        	}
			return _value;
        }
        
        var _loadStyleFunctions = function(){
        	$(".ghost").hide();
            $( ".datepicker" ).datepicker();
            
            
            if(_isDynamic())
        	{
            	$(".dynBtn" +s.settings.id).each(function (){
            		var name = $(this).attr("name");
            		$(this).click($.proxy(s.dellRow,s,name)); 
            	});
            	
        	}
            
            if(s.settings.expand.exp  )
    		{
	            $(".dynSpanTr" +s.settings.id).each(function (){
	        		$(this).click($.proxy(s.openHideKids,s,this)); 
	        	});
	            
	            $(".dynSpanTr" +s.settings.id).each(function (){
	            	$(this).click();
	            });
    		}
            
        }
        
        var _paintHeader = function(){
        	var r ='<thead> <tr class=" ">';
        	var model = s.settings.colModel;
        	for ( _i=0;_i< model.length;_i++) {
        	    r+= "<th ";
        	    if( typeof model[_i].width != 'undefined')  r+=" width='"+model[_i].width+" !important' " ; 
        	    r+=_generateVisibleClass(model[_i] );
        	    r+=	" >"+model[_i].header+"</th>";
        	}
        	
        	if(_isDynamic())
        	{
        		r+="<th> <button id='"+s.settings.id+"AddButton' type='button'> <span><b style='color:black'>+</b></span> </button> </th>";
        	}
        	
        	r+=' </tr>  </thead>';
        	return r;
        }
        
        var _paintBody = function(){
        	var r ='<tbody>';
        	var items = s.settings.items;
        	
        	var _itms=[];
        	for(_j=0 ; _j< items.length;_j++)
        	{
        		if(s.settings.expand.exp && typeof items[_j][s.settings.expand.attribute] !== 'undefined'  
        			&& items[_j][s.settings.expand.attribute] != null )
        		{
        			items[_j]["isParent"]=true;
        			_itms.push(items[_j]);
        			var parentIndex = _itms.length-1;
        			for(_i=0 ; _i< items[_j][s.settings.expand.attribute].length;_i++)
                	{
        				items[_j][s.settings.expand.attribute][_i]["parentIndex"+s.settings.id] = parentIndex;
        				items[_j][s.settings.expand.attribute][_i]["isParent"]=false;
        				_itms.push(items[_j][s.settings.expand.attribute][_i]);
                	}
        		}
        		else
        		{
        			items[_j]["isParent"]=false;
        			_itms.push(items[_j]);
        		}
        	}
        	s.settings.items = _itms;
        	for(_j=0 ; _j< _itms.length;_j++)
        	{
        		r+=_paintRow(_itms[_j], _j);
        	}
        	r+='</tbody>';
        	return r;
        }
		
        var _paintRow = function(item , index){
        	var model = s.settings.colModel;
        	var r="<tr "
        	r+=  _generateRowClass(item , index)   +" >";
        	
        	
        	for(_i=0 ; _i< model.length;_i++)
        	{
        		r+="<td ";
        		r+ typeof model[_i].width != 'undefined' ? "width='"+model[_i].width+" !important' " : ""; 
        		r+=_generateVisibleClass(model[_i] );
        		r+=" >";
        		r+=_paintTDContent(item,model[_i],index);
        		r+="</td>";
        	}
        	if(_isDynamic())
        	{
        		r+="<td><button class='dynBtn" +s.settings.id+
        				"' type='button'   name='"+index+"' > <span><b>x</b></span> </button></td>";
        	}
        	r+="</tr>";
        	return r;
        }
        
        var _paintTDContent = function(item, model,index){
        	var r = "";
        	var value = _deepFind( item,model.name);
        	if(typeof model.customRender === 'undefined' )
        	{
        		value = ( typeof value == 'undefined' ) ? '' :  value;
        		
        		value = (value == null  || typeof value == 'undefined') ? '':value; 
        		
        		if(model.date == true )
        		{
        			if(value != null  && value != "" && typeof value != 'undefined'){
	        			value = s.changeDateFormat(s.settings.dateFormatIn,s.settings.dateFormatOut,value);
        			}
        		}
        		
        		if(s.settings.edit )
            	{
        			var name = s.settings.prefix+"["+ index+"]."+model.name;
            		r+= "<input id='"+s.settings.id+name+"' name='"+name+"' type='text' " +
            				"class=' form-control "+_generateInputClass(model)+"' value='"+ value +"' "
            				+  _generateInputReadOnly(model)+"  />";
            	}
            	else { 
            		//Agrega simbolo mas o menos para expandir o contraer renglones
            		if(s.settings.expand.exp && s.settings.expand.column == model.name && item["isParent"] )
            		{
                            r+="<p class='text-primary'><i class='dynSpanLabel dynTrIco"+s.settings.id+index+" fa fa-minus'></i>"+value+"</p>";
            		}
                    else { r+=value; }
            		
            	}
        	}
        	else 
        	{ //se usa una funcion custom para renderizar la columna
        		r += model.customRender(item, model,index,value);
        	}
        	
        	return r;
        }
        
        var _generateInputClass = function(model){
        	var c ="";
        	c+=(model.date == true &&  (model.readonly ==  false  || typeof model.readonly == 'undefined') ) ||
        	   (model.date == true &&  s.settings.dyn == true  )? " datepicker" :"";
        	c+=(model.required == true) ? " required" :"";
        	c+=(model.digit == true) ? " digit" :"";
        	return c;
        }
        
        var _generateRowClass = function(item,index){
        	var c =" class='dynTr"+s.settings.id+index;
        	c+=( typeof item["parentIndex"+s.settings.id] != 'undefined' && item["parentIndex"+s.settings.id] != null) 
        		? 
        				" dynTrParent"+s.settings.id+item["parentIndex"+s.settings.id] :"";
        	c+=(item["isParent"] ) ? " dynSpanTr"+s.settings.id+ " dynOpenTR" :"";
        	c+="'   index='"+index+"'";
        	return c;
        }
        
        var _generateInputReadOnly = function(model){
        	var c ="";
        	c+=(model.readonly == true) ? " readonly" :"";
        	return c;
        }
        
        var _generateVisibleClass = function(model){
        	var c ="class='";
        	c+=(model.visible == false) ? " ghost" :"";
        	c+="'";
        	return c;
        }
        
        var _deepFind = function(obj,path){
        	var c =obj;
        	path.split('.').forEach(function(i){ c = c[i]  }  );
        	return c;
        }
        
        s.construct();
        return s;

 };

$.fn.dynTable = function(options) {
		var dt = new $.dynTable(this, options);
		var dyn = $("#"+this.attr('id'));
		$.data( dyn, "dyn", dt);
        return dt;
    };

	}( jQuery ));