// generated by FBuilder
package flexa.ff;
import flexa.fb.*;
import java.util.Map;
import java.util.HashMap;
import javax.script.*;
import java.util.ArrayList;
public class table extends FComponent {
    //
    // CONSTRUCTOR
    //
    public table() {
        super("ff.table");
    }
    
    // 
    // Methods
    //
    
    
    public void buildRowsFromResult(FResult result)  throws Exception { 
    		//  
		Log.info("ff:table buildRowsFromResult"); 
		//Log.info("ff:table buildRowsFromResult : " + result); 
		int totalrows = result.size(); 
		 
		 
		//FComponent tbody = this.findChildOfType("tr", "type", "body"); 
		//@todo buscar one row for body  
		//if( tbody == null )  
		//if( tbody == null ) throw new Exception("No TR body found on table " + (String)getValue("name"));   // @todo armar filas con FResult 
		//int tposition = this.getChildren().indexOf(tbody); 
		//FComponent torender = tbody; 
		//String tid = (String)torender.getValue("id"); 
		// Por cada registro genera TR 
		tr torender = null; 
		String tid = ""; 
		this.clearChildren(); 
		for(int i = 0; i < totalrows; i++) { 
		    FRow row = result.get(i); 
		    //Log.getInstance().info("TR from row " + i); 
		    // Header  @todo with resulmeta for empty results 
		    if( i == 0 ) {  
		        tr trheader = new tr(); 
		        trheader.setValue("id", this.id + "_header"); 
		        trheader.setValue("name", this.id + "_header"); 
		        trheader.setValue("type", "header"); 
		        trheader.buildHeaderFromFRow(row, (String)this.getValue("columnstitle")); 
		        trheader.status = 1; 
		        this.addChild(trheader); 
		    } 
		     
		    // Clone and add to father 
		    torender = new tr(); 
		    tid = this.id + "[" + i + "]"; 
		    torender.setValue("id", tid); 
		    torender.setValue("name", tid); 
		    torender.setValue("type", "body"); 
		    torender.status = 1; 
		    torender.buildFromFRow(row); 
		    this.addChild(torender); 
		    //torender.setValue("id", tid + "[" + i + "]"); 
		}

    }
    


    
    public Object call(FContextInterface contexti, String aname, Object... args)  throws Exception { 
    		Log.info("Call " + aname); 
		switch(aname) { 
		    case "buildRowsFromResult": 
		        buildRowsFromResult((FResult)args[0]); 
		        break; 
		     case "refresh":
		        event(this.name + ".refresh", (FContext)contexti);
		        break;
		} 
		return null;

    }
    









    // 
    // Events
    //
	public void event(String aAction, FContext aContext) throws Exception {
        // Events
        
    
        // onopen EVENT
        if( LibText.stringToArray("" + this.name + ".select," + this.name + ".refresh,start,onopen," + this.name + ".search," + this.name + ".sort").contains(aAction) ) {
        			//Log.info("Table " + this.name + " onopen"); 
			//Log.info("datasource_oql", this.get("datasource_oql")); 
			//Log.info("datasource_sql", this.get("datasource_sql")); 
			//Log.info("status", this.status); 
			if( aAction.equals(this.name + ".search") && aContext.hasMember("q") ) { 
			    this.setValue("searchtext", aContext.get("q").toString());
			}  else {
			    this.setValue("searchtext", "");
			}
			if( aContext.hasMember("_sort") ) {
			    String tsort = aContext.get("_sort").toString();
			    this.setValue("sortby",  tsort);
			    Log.info("SORT " + tsort);
			    ArrayList<FComponent> theaders = findChildsOfType("tr", "type", "header");
			    if( theaders.size() > 0 ) {
			        int index = theaders.get(0).indexOfChild("value", tsort.replace(" asc", "").replace(" desc", ""));
			        int ii = 0;
			        for (FComponent child : theaders.get(0).getChildren()) {
			            child.setValue("sorted", ii == index ? "asc" : "");
			            ii++;
			        }
			        Log.info("Child index of " + tsort.replace(" asc", "").replace(" desc", "") + " : " + index);
			    }    
			    
			    
			}
			String trender = (String)this.getValue("renderoptions");
			if( trender == null || trender.equals("") ) trender = "server";
			//if( this.status == 0 && (hasValue("datasource_oql") || hasValue("datasource_sql"))    ) { 
			if( (hasValue("datasource_oql") || hasValue("datasource_sql"))    ) { 
			    // EXECUTES SQL/OQL 
			    Log.info("refresh table " + this.id + " processing datasource"); 
			    //Log.info(aContext.toString()); 
			    FResult result = this.processDatasource(aContext); 
			    //Log.info("   result" , result); 
			    // If client render stop now. Put result in object for sending by json 
			    if( trender.equals("client") ) {
			        this.setValue("result", result);
			        return;
			    }
			    
			 
			    // Clone TRs from result 
			    this.removeClonedChildren();  // eliminar clonados demas de anteriores clonaciones 
			 
			    // Get rows 
			    int totalrows = result.size(); 
			    Log.info("result size", totalrows);
			    ArrayList<FComponent> tbody = this.findChildsOfType("tr", "type", "body"); 
			    tbody.addAll(this.findChildsOfType("tr", "type", "")); 
			    ArrayList<FComponent> theadergroup = this.findChildsOfType("tr", "type", "headergroup"); 
			    ArrayList<FComponent> tfootergroup = this.findChildsOfType("tr", "type", "footergroup"); 
			    ArrayList<FComponent> tfooter = this.findChildsOfType("tr", "type", "footer"); 
			    String tgroupby = (String)getValue("groupby"); 
			    
			    Log.info("body", tbody);
			     
			     
			    // If no rows, build TRs & TDs from result 
			    if( tbody.size() == 0 ) { 
			        buildRowsFromResult(result); 
			        return; 
			        //throw new Exception("No TR body found on table " + (String)getValue("name"));   // @todo armar filas con FResult 
			    } 
			     
			     
			 
			    // Position next to last body row
			    int tposition = this.getChildren().indexOf(tbody.get(tbody.size() - 1)) + 1; 
			    FComponent torender = null; 
			    FComponent torender2 = null; 
			    //String tid = (String)torender.getValue("id"); 
			     
			     
			    // Por cada registro clona elemento 
			    Object tlastgroupby = null; 
			    int tgroupid = 0; 
			    FRow row = null; 
			    FRow lastrow = null; 
			     
			    for(int i = 0; i < totalrows; i++) { 
			        row = result.get(i); 
			        //Log.getInstance().info("TR body ds row " + i); 
			        //Log.getInstance().info(row.toString()); 
			             
			        // Group by header/footer 
			        if( tgroupby != null ) { 
			            this.context = new FContext(row); 
			            Object tgroupbyval = this.calcExpression(aContext, "groupby"); 
			             
			            // Context for first header group 
			            if( i == 0 ) { 
			                for( FComponent ttr : theadergroup) { 
			                    ttr.context = new FContext(row); 
			                } 
			            } 
			             
			            // Cambio de valor de grupo, cambio de grupo
			            if( i > 0 && !tgroupbyval.equals(tlastgroupby) ) { 
			                tgroupid++; 
			            
			                // Last row Footers group 
			                // Clone footers 
			                for( FComponent ttr : tfootergroup) { 
			                    torender2 = (FComponent)ttr.clone(); 
			                    torender2.setValue("id", ttr.getValue("id") + "[" + tgroupid + "]"); 
			                    torender2.context = new FContext(lastrow); 
			                    this.addChild(torender2, tposition ); 
			                    tposition++; 
			                } 
			                //Log.info("Changed group by i" + i + " " + tgroupbyval); 
			 
			                // New row header groups
			                for( FComponent ttr : theadergroup) { 
			                    // Header group 
			                    torender2 = (FComponent)ttr.clone(); 
			                    //tlastgroupby 
			                    torender2.setValue("id", ttr.getValue("id") + "[" + tgroupid + "]"); 
			                    torender2.context = new FContext(row); 
			                    this.addChild(torender2, tposition ); 
			                    tposition++; 
			                } 
			            } 
			            tlastgroupby = tgroupbyval; 
			        } 
			         
			         
			        if( i > 0 ) { 
			            // Clone and add to father 
			            //torender = (FComponent)PipedDeepCopy.copy(this); 
			            for( FComponent ttr : tbody) { 
			                torender = (FComponent)ttr.clone(); 
			                //torender = new FComponent(this); 
			                torender.setValue("id", ttr.getValue("id") + "[" + i + "]"); 
			                torender.context = new FContext(row); 
			                this.addChild(torender, tposition); 
			                tposition++; 
			            } 
			        } else { 
			            for( FComponent ttr : tbody) { 
			                ttr.context = new FContext(row); 
			                ttr.status = 0;
			            } 
			        } 
			        //Log.info("Row moredata:"); 
			        //Log.info(row.toString()); 
			        //Log.info(((FObject)row.get("x")).info()); 
			        //torender.moreData = row; 
			         
			        // ?? torender.setValuesOnlyDefinition(row); 
					// ?? torender.setValuesOnDescendants(row); 
			         
			         
			        //Log.getInstance().info("Torender " + torender.getValue("id")); 
			         
			        // ?? torender.calcExpressions(aContext); 
			         
			        lastrow = row; 
			    } 
			    // Footer group 
			    if( totalrows > 0 && tgroupby != null && tfootergroup != null ) { 
			        for( FComponent ttr : tfootergroup) { 
			            ttr.context = new FContext(row); 
			        } 
			    } 
			     
			    if( tfooter != null ) { 
			        for( FComponent ttr : tfooter) { 
			            ttr.context = new FContext(result); 
			        } 
			    } 
			    
			    // If no results, status -1 to body rows (@todo groupheader / footerheader)
			    if( totalrows == 0 ) {
			        Log.info("Hiding body", tbody);
			        for( FComponent ttr : tbody) { 
			            Log.info("Hiding body row", ttr);
			            ttr.status = -1;
			        } 
			    }
			 
			    //Log.getInstance().info("TABLE EVENT end: " + torender.info()); 
			    // @todo eliminar clonados demas de anteriores clonaciones 
			    // @todo si no hay registros limpiar elemento y ponerlo como inactivo (status -1) 
			}

        }
    


	    super.event(aAction, aContext);
	}
	
	
}