/**
 * Classes for mapping MySQL tables to grids and forms
 */

//Classes for controlling a checkbox item in an editable grid
Ext.grid.CheckColumn = function(config){
    Ext.apply(this, config);
    if(!this.id){
        this.id = Ext.id();
    }
    this.renderer = this.renderer.createDelegate(this);
};

Ext.grid.CheckColumn.prototype = {
    init : function(grid){
        this.grid = grid;
        this.grid.on('render', function(){
            var view = this.grid.getView();
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    onMouseDown : function(e, t){
        if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);
            record.set(this.dataIndex, !record.data[this.dataIndex]);
        }
    },

    renderer : function(v, p, record){
        p.css += ' x-grid3-check-col-td'; 
        return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'">&#160;</div>';
    }
};					

var MySQL = {
	
	//Retrieve the schema for a mysql table. The callback is expected to take the schema as a parameter
	get_schema : function(url, db, table, callback) {
		
		var self = this;
		
		//Conduct an AJAX request to the server to retrieve schema information
		Ext.Ajax.request({
			url : url,
			method : 'POST',
			params : {
				action : 'db_define',
				db : db,
				table : table
			},
			success : function(response) {
				var result = Ext.util.JSON.decode(response.responseText);

				if (result.success) {
					if (result.schema) {
						callback(MySQL.extify(result.schema));
					}
					else {
						Ext.Msg.alert('Error', 'Failed to retrieve schema information for ' + db + '.' + table);
					}
				}
				else {
					Ext.Msg.alert('Error', result.message);
				}
			},
			failure : function(response) {
				Ext.Msg.alert('Error', response.responseText);
			}
		});		
	},
		
	//Build a column model to represent a schema
	get_column_model : function(schema) {
		var cols = [];
		
		for (var name in schema.COLUMNS) {
			if (typeof schema.COLUMNS[name] === 'function') continue;
			var item = schema.COLUMNS[name];
			var col = item.column;
			var editor = item.editor;
			col.editor = editor;
			cols.push(col);
		};
		var cm = new Ext.grid.ColumnModel(cols); 
	    cm.defaultSortable = true;
		return cm;
	},
		
	//Assign ExtJS compatible values to schema objects
	extify : function(schema) {
		
		for (var name in schema.COLUMNS) {
			if (typeof schema.COLUMNS[name] === 'function') continue;

			var item = schema.COLUMNS[name];

			item.field = {};
			item.editor = {};
			item.column = {};
			
			switch (item.DATA_TYPE) {
				
				case 'char':
				case 'varchar':
				case 'tinytext':
				case 'tinyblob':
					item.editor = new Ext.form.TextField({
						maxLength : parseInt(item.CHARACTER_MAXIMUM_LENGTH)
					});
					item.field.type = 'string';
					break;
				
				case 'text':
				case 'mediumtext':
				case 'longtext':
				case 'blob':
				case 'mediumblob':
				case 'longblob':			
					item.editor = new Ext.form.TextArea({
						maxLength : parseInt(item.CHARACTER_MAXIMUM_LENGTH)
					});
					item.field.type = 'string';
					break;
	
				case 'tinyint':
				case 'smallint':
				case 'int':
				case 'mediumint':
				case 'bigint':
					item.editor = new Ext.form.NumberField({
						allowDecimals : false
					});
					item.field.type = 'int';
					break;
				
				case 'float':
				case 'float unsigned':
				case 'double':
				case 'decimal':
					item.editor = new Ext.form.NumberField({
						allowDecimals : true
					});
					item.field.type = 'float';
					break;
	
				case 'time':
					item.editor = new Ext.form.TimeField({
						format : 'H:i:s'
					});
					item.field.type = 'string';
					break;
					
				case 'timestamp':
				case 'datetime':
					item.editor = new Ext.form.DateField({
						format : 'Y-m-d H:i:s'
					});
					item.field.type = 'date';
					item.field.dateFormat = 'Y-m-d H:i:s';
					break;

				case 'date':
					item.editor = new Ext.form.DateField({
						format : 'Y-m-d'
					});
					item.field.type = 'date';
					item.field.dateFormat = 'Y-m-d';
					break;

				case 'bit':
					item.editor = Ext.grid.CheckColumn({
					});
					item.field.type = 'bool';					
					break;
	
				case 'set':
				case 'enum':
					var parts = item.COLUMN_TYPE.split('(');
					var parts = parts[1].split(')');
					var parts = parts[0].split(',');
	
					for (var i=0; i<parts.length; i++) {
						parts[i] = parts[i].substr(1,parts[i].length-2);
					}
					var array = [];
					for (var i=0; i<parts.length; i++) {
						array.push([parts[i]]);
					}
					
					item.editor = new Ext.form.ComboBox({
					    store: new Ext.data.SimpleStore({
							fields : [0],
							data : array
						}),
					    typeAhead: true,
					    mode: 'local',
					    triggerAction: 'all',
					    selectOnFocus:true,
						forceSelection :true,
						lazyRender:true,
						listClass: 'x-combo-list-small'
					});

					item.field.type = 'string';
					break;
				
				default:
					break;
			}
			
			//Add params to the field object
			item.field.name = item.COLUMN_NAME;

			//Add params to the editor object
			Ext.apply(item.editor, {
				fieldLabel : Ext.util.Format.capitalize(item.COLUMN_NAME.replaceAll('_',' ')),
				name : item.COLUMN_NAME,
				allowBlank : item.IS_NULLABLE && item.IS_NULLABLE == 'YES'
			});
			
			//Add params to the column definition object
			item.column.id = item.COLUMN_NAME;
			item.column.header = Ext.util.Format.capitalize(item.COLUMN_NAME.replaceAll('_',' '));
			item.column.dataIndex = item.COLUMN_NAME;
			item.column.width = 80;
		};
		return schema;
	},
	
	//Build a record object to represent the schema
	get_record : function (schema) {
		var defs = [];
		
		for (var name in schema.COLUMNS) {
			if (typeof schema.COLUMNS[name] === 'function') continue;
			var item = schema.COLUMNS[name];
			defs.push(item.field);
		};
		return Ext.data.Record.create(defs);
	},
	  	
	//Build a data store to represent a schema
	get_store : function(schema, url) {
		var ds = new Ext.data.Store({
			proxy  : new Ext.data.HttpProxy({
				url : url
			}),
			reader : new Ext.data.JsonReader({
				totalProperty: 'count',
				root : 'rows',
				id : schema.PKEY
			}, MySQL.get_record(schema)),
			baseParams : {
				db : schema.DATABASE_NAME,
				table : schema.TABLE_NAME,
				action : 'db_multiple_select'
			},
			remoteSort:true
		});
		ds.setDefaultSort(schema.PKEY, 'ASC');
		return ds;
	},
	
	//Get an empty record
	get_blank_record : function(schema) {
		var defaults = {};

		for (var name in schema.COLUMNS) {
			if (typeof schema.COLUMNS[name] === 'function') continue;
			var item = schema.COLUMNS[name];

			switch (item.field.type) {
				case 'bool'   : value = true;       break;
				case 'float'  : value = 0.0;        break;
				case 'int'    : value = 0;          break;
				case 'string' : value = '';         break;
				case 'date'   : value = new Date(); break;
				default : value = null;
			}
			defaults[item.COLUMN_NAME] = value;
		};
		return new (MySQL.get_record(schema))(defaults);
	},
	
	//Get an array of column names from the schema
	get_columns : function(schema) {
		var array = new Array();

		for (var name in schema.COLUMNS) {
			if (typeof schema.COLUMNS[name] === 'function') continue;
			var item = schema.COLUMNS[name];
			array.push([item.COLUMN_NAME]);
		}
		return array;
	}
}