/*!
 * Fancy Table
 * Copyright(c) 2010 Harry Sorensen
 * 
 * @class Ext.hs.FancyTable
 * @extends Ext.grid.EditorGridPanel
 * @constructor
 * @param {Object} config Configuration options
 */


Ext.namespace('HS');
/**
 * HS.FancyTable
 * A EditorGridPanel extension that showcases possibilities for data graphing and retrieval from an XML store
 */

HS.FancyTable = Ext.extend(Ext.grid.EditorGridPanel, {

	initComponent : function() {
	    // typical viewConfig
	    this.viewConfig = {
	        forceFit: true
	    };

	    // relay the Store's CRUD events into this grid so these events can be conveniently listened-to in our application-code.
	    //this.relayEvents(this.store, ['destroy', 'save', 'update']);

	    // build toolbars and buttons.
	    this.tbar = this.buildTopToolbar();
	    this.bbar = this.buildBottomToolbar();

	    // super
	    HS.FancyTable.superclass.initComponent.call(this);
	},
	
    /**
     * buildTopToolbar
     */
    buildTopToolbar : function() {
        return [{
            text: 'Save',
            id: 'ftsavebutton', // Doing the quick and dirty way to enable/disable this button
            iconCls: 'icon-save',
            disabled: true,
            handler: this.onSave,
            scope: this
        },'-',{
            iconCls: 'icon-add',
            text: 'Add Fillup',
            handler : this.onAdd,
            scope: this
        },'-',{
            iconCls: 'icon-del',
            text: 'Remove Fillup',
            handler : this.onDelete,
            scope:this
        }];
    },

    /**
     * buildBottomToolbar
     */
    buildBottomToolbar : function() {
        return ['Show: ',{
            text: 'Chart',
			enableToggle: true,
			toggleGroup: 'visualization',
            iconCls: 'icon-chart',
            toggleHandler: this.showChart,
            scope: this
        },'-',{
            iconCls: 'icon-python',
            text: 'Python',
			enableToggle: true,
			toggleGroup: 'visualization',
            toggleHandler : this.showPython,
            scope: this
        },'-',{
            iconCls: 'icon-xml',
            text: 'XML',
			enableToggle: true,
			toggleGroup: 'visualization',
            toggleHandler : this.showXML,
            scope:this
        },'-',{
            iconCls: 'icon-json',
            text: 'JSON',
			enableToggle: true,
			toggleGroup: 'visualization',
			toggleHandler : this.showJSON,
            scope:this
       }];
    },
    /**
     * onSave - It sure would be great to have access to each CRUD call, concurrency is a bitch with a simple backend
     */
	onSave: function(b,e){
    	this.store.save()
    },
    /**
     * onAdd - need to figure out a way to call /create and /update serially
     *
     */
	onAdd: function(b,e){
    	var f = new this.store.recordType({
    		filldate: new Date(),
    		mpg: 20
    	})
    	this.stopEditing();
    	this.store.insert(0,f);
    	this.startEditing(0,1);
    	Ext.getCmp('ftsavebutton').enable();
    },
    /**
     * onDelete - need to serialize this by UPDATEing the data before calling REMOVE
     */
    onDelete : function(b, e) {
    	//this.store.save(); Can probably attach a handler so that saves are handled serially, then remove it.
        var index = this.getSelectionModel().getSelectedCell();
        if (!index) {
            return false;
        }
        var rec = this.store.getAt(index[0]);
        this.store.remove(rec);
//        this.store.save();
    	Ext.getCmp('ftsavebutton').enable();
    },
    /**
     * showChart
     */
    showChart : function(b,e){
    	if (undefined == this.chart){
    		this.chart = new Ext.Window({
    			layout: 'hbox',
    			layoutConfig:{
    				align:'middle',
    				pack:'center'
    			},
		        closable: false,
		        resizable: false,
		        draggable: false,
		        animateTarget: this.el,
		        bodyStyle: 'background:#FFFFFF',
		        width:600,
		        height:300,
		        x: this.getPosition()[0],
		        y: this.getPosition()[1]+this.getHeight(),
		        items:[{
		        	xtype: 'box',
		        	id: 'mpgplot',
		        	autoEl: {
		            	tag: 'img',
		            	src: '/cgi-bin/mpgplot.py'
		        	}}]
    		});
    		this.chart.on('afterrender',function(c){
    			var mpgplot = Ext.fly('mpgplot');
    			mpgplot.setHeight(c.body.getHeight());
    			mpgplot.dom.onload = function(){
    				c.doLayout();
    			};
    		});
			this.chart.render(this.getEl());
        	this.chart.anchorTo(this.getEl(),'bl');
    	}
		if (b.pressed){
			this.chart.show();
		} else {
			this.chart.hide();
		}
    },
    /**
     * showXML
     */
	showXML : function(b,e){
    	if (undefined == this.xmlpanel){
    		this.xmlpanel = new Ext.Window({
    			layout: 'fit',
    			layoutConfig:{
    				align:'middle',
    				pack:'center'
    			},
		        closable: false,
		        resizable: false,
		        draggable: false,
		        animateTarget: this.el,
		        bodyStyle: 'background:#FFFFFF',
		        width:600,
		        height:300,
		        x: this.getPosition()[0],
		        y: this.getPosition()[1]+this.getHeight(),
	        	tpl: new Ext.XTemplate(
        			'<code><pre>',
        			Ext.util.Format.htmlEncode('<?xml version="1.0" encoding="UTF-8"?>'),
        			'<br>',
        			Ext.util.Format.htmlEncode('<root>'),
        			'<br>',
        			'<tpl for=".">',
        			Ext.util.Format.htmlEncode('    <Fillup><id>{id}</id><Date>'),
        			'{[fm.date(values.filldate)]}',
        			Ext.util.Format.htmlEncode('</Date><MPG>{mpg}</MPG></Fillup>'),
        			'<br>',
        			'</tpl>',
        			Ext.util.Format.htmlEncode('<root>'),
        			'</pre></code>'),
	        	data: this.store.getData(),
	        	autoScroll: true,
	        	id: 'xmlpanel'
    		});
			this.xmlpanel.render(this.getEl());
        	this.xmlpanel.anchorTo(this.getEl(),'bl');
    	}
		if (b.pressed){
			this.xmlpanel.show();
		} else {
			this.xmlpanel.hide();
		}
    },
    /**
     * showJSON
     */
	showJSON : function(b,e){
    	if (undefined == this.jsonpanel){
    		this.jsonpanel = new Ext.Window({
    			layout: 'fit',
    			layoutConfig:{
    				align:'middle',
    				pack:'center'
    			},
		        closable: false,
		        resizable: false,
		        draggable: false,
		        animateTarget: this.el,
		        bodyStyle: 'background:#FFFFFF',
		        width:600,
		        height:300,
		        x: this.getPosition()[0],
		        y: this.getPosition()[1]+this.getHeight(),
	        	tpl: new Ext.XTemplate(
        			'<code><pre>[',
        			'<tpl for=".">',
        			Ext.util.Format.htmlEncode('    {"id":{id},"Date":"'),     			
        			'{[fm.date(values.filldate)]}',
        			Ext.util.Format.htmlEncode('","MPG":{mpg}}'),  
        			'{[xindex === xcount ? "":","]}',
        			'<br>',
        			'</tpl>',
        			']</pre></code>'),
	        	data: this.store.getData(),
	        	autoScroll: true,
	        	id: 'jsonpanel'
    		});
			this.jsonpanel.render(this.getEl());
        	this.jsonpanel.anchorTo(this.getEl(),'bl');
    	}
		if (b.pressed){
			this.jsonpanel.show();
		} else {
			this.jsonpanel.hide();
		}
    },
    /**
     * showPython
     */
	showPython : function(b,e){
    	if (undefined == this.pythonpanel){
    		this.pythonpanel = new Ext.Window({
    			layout: 'fit',
    			layoutConfig:{
    				align:'middle',
    				pack:'center'
    			},
		        closable: false,
		        resizable: false,
		        draggable: false,
		        animateTarget: this.el,
		        bodyStyle: 'background:#FFFFFF',
		        width:600,
		        height:300,
		        //x: this.getPosition()[0],
		        //y: this.getPosition()[1]+this.getHeight(),
	        	tpl: new Ext.XTemplate(
        			'<code><pre>[ ',
        			'<tpl for=".">',
        			Ext.util.Format.htmlEncode("    {'id':{id},'Date':'"),
        			'{[fm.date(values.filldate)]}',
        			Ext.util.Format.htmlEncode("','MPG':{mpg}}"),       			
        			'{[xindex === xcount ? "":","]}',
        			' &#92;<br>',
        			'</tpl>',
        			']</pre></code>'),
	        	data: this.store.getData(),
	        	autoScroll: true
    		});
			this.pythonpanel.render(this.getEl());
        	this.pythonpanel.anchorTo(this.getEl(),'bl');
    	}
		if (b.pressed){
			this.pythonpanel.show();
		} else {
			this.pythonpanel.hide();
		}
    }

});

/**
 * Handler specified for the 'filldate' column renderer
 * @param {Object} value
 */
function formatDate(value){
    return value ? value.dateFormat('M d, Y') : '';
}
var bs = Ext.util.Format.htmlEncode('\\');
//var chart = new Ext.Panel({border:false,autoScroll:true,layout:'fit'});


////
//all write events
//
//var dr = Ext.util.Format.dateRenderer('m/d/Y')
Ext.data.DataProxy.addListener('beforewrite', function(proxy, action, rs, params) {
 //Ext.Msg.show({title:'beforewrite',msg:action});
//	if (rs.length >0){
//		for (var i=0;i<rs.length;++i){
//			var rec = rs[i];
//		}
//	} else {
//		console.log('  pre '+rs.data.filldate);
//		rs.data.filldate = Ext.util.Format.date(rs.data.filldate);
//		console.log('  post'+rs.data.filldate);
//	}
//	console.log('End beforewrite');
});
Ext.data.DataProxy.addListener('write', function(proxy, action, result, res, rs) {
	//console.log('Afterwrite: '+res.message+' action: '+action);
	Ext.getCmp('ftsavebutton').disable();  // Here for destroy actions
	var plot = Ext.fly('mpgplot')
	if (plot != undefined){
		//console.log('  plot: '+plot);
		plot.dom.src = '/cgi-bin/mpgplot.py?a='+(new Date()).getTime(); // Force reload of chart
	}
	//	console.log('afterwrite '+new Date());
});

////
//all exception events
//
Ext.data.DataProxy.addListener('exception', function(proxy, type, action, options, res) {
	console.log('Exception: '+res+' action: '+action);
});

var ftstore = new Ext.data.Store({
    // store configs
    autoDestroy: true,
	proxy: new Ext.data.HttpProxy({
	    api: {
	        read : '/cgi-bin/xmlstore.py/read',
	        create : '/cgi-bin/xmlstore.py/create',
	        update: '/cgi-bin/xmlstore.py/update',
	        destroy: {  // <--- Supports object-syntax as well
				url: '/cgi-bin/xmlstore.py/destroy',
				method: "DELETE"
        	}
	    }
	}),


	// reader configs
    reader: new Ext.data.XmlReader({
        // records will have a 'plant' tag
        record: 'Fillup',
        successProperty: 'success',
        messageProperty: 'message',
        id: 'id',
        // use an Array of field definition objects to implicitly create a Record constructor
        fields: [
            {name: 'id', mapping: 'id', type: 'int'},
            {name: 'filldate', mapping: 'Date', type: 'date', dateFormat: 'n/j/Y'},
//            {name: 'filldate', mapping: 'Date', type: 'date'},
            {name: 'mpg', mapping: 'MPG', type: 'float'}
        ]
    }),
    writer: new Ext.data.XmlWriter({
    	//documentRoot: 'root',
    	root: 'root',
    	writeAllFields:true,
    	tpl: new Ext.XTemplate(
    		'<?xml version="{version}" encoding="{encoding}"?>\n',
    		'<tpl if="documentRoot"><{documentRoot}>\n</tpl>',
    		'<tpl for="baseParams">',
    		'<tpl for=".">',
    		'  <{name}>{value}</{name}>\n',
    		'</tpl>',
    		'</tpl>',
    		'<tpl if="records.length &gt; 1"><{root}>\n</tpl>',
    		'<tpl for="records">',
    		'  <{parent.record}>\n',
    		'<tpl for=".">',
    		'    <{name}>{[values.name == \'Date\' ? fm.date(values.value):values.value]}</{name}>\n',
    		'</tpl>',
    		'  </{parent.record}>\n',
    		'</tpl>',
    		'<tpl if="records.length &gt; 1"></{root}>\n</tpl>',
    		'<tpl if="documentRoot"></{documentRoot}></tpl>')
    }),
    autoSave: false,
    sortInfo: {field:'filldate', direction:'ASC'},
    getData: function(){
		var storearr = this.getRange();
		var len = storearr.length;
		var dat = new Array(len);
		for (var i=0; i<len; ++i){
			dat[i]=storearr[i].data;
		}
		return dat;   	
    }
});
ftstore.on('update',function(store, record, op){
	if ((Ext.data.Record.EDIT == op)||(Ext.data.Record.REJECT == op)) {Ext.getCmp('ftsavebutton').enable();}
	//if (Ext.data.Record.COMMIT == op) {Ext.getCmp('ftsavebutton').disable();}
});
ftstore.on('save',function(store, record, op){
	/* This is unbelievebly ugly, needs to be fixed.  Can't rely on the object always being named ftgrid */
	var newdata = store.getData();
	var ftgrid = Ext.getCmp('myfancytable'); // Ugh
	if (ftgrid.xmlpanel != undefined){
		//console.log('  xmldump: '+xmldump); // Reload data in xml page
		ftgrid.xmlpanel.update(newdata);
	}
	if (ftgrid.jsonpanel != undefined){
		ftgrid.jsonpanel.update(newdata);
	}
	if (ftgrid.pythonpanel != undefined){
		ftgrid.pythonpanel.update(newdata);
	}
});

// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel({
    // specify any defaults for each column
    defaults: {
        sortable: true // columns are not sortable by default           
    },
    columns: [
        {
            id: 'filldate',
            header: 'Fill Date',
            dataIndex: 'filldate',
            //width: 90,
            renderer: formatDate,
	        editor: new Ext.form.DateField({
	            format: 'm/d/Y'
//	            minValue: '10/01/2004',
//	            disabledDays: [0, 6],
//	            disabledDaysText: 'Plants are not available on the weekends'
	        })
        }, {
            header: 'Miles per Gallon',
            dataIndex: 'mpg',
            //width: 70,
            align: 'right',
            editor: new Ext.form.NumberField({
                allowBlank: false,
                allowNegative: false,
                maxValue: 50
            })
        }]
});

// create the editor grid
//var ftgrid = new HS.FancyTable({
//    store: ftstore,
//    cm: cm,
////    renderTo: 'fancytable',
//    width: 600,
//    height: 300,
//    autoExpandColumn: 'filldate', // column with this id will be expanded
//    title: 'STI Gas Mileage',
//    frame: true,
//    clicksToEdit: 1,
//});



