 
// replace " in strings
function qt(x) {
	if (typeof(x) === typeof('abc')) {
		return x.replace(/\"/g,'&quot;');
	}
	else {
		return x;
	}
}

// format group elements
function fmt(v) {
	function fmt_grp(x) {
		var b = [], val, j, i;
		for (i in x) {
			if (x.hasOwnProperty(i)) {
				j = x[i];
				if (typeof(j) === 'object' && j.constructor === Array) {
					j = fmt_grp(j);
				}
				else if (typeof(j) === typeof(1) || typeof(j) === typeof(1.01)) {
					j = j;
				}
				else {
					j = '"'+j+'"';
				}
				b.push(j);
			}
		}
		val = '{'+(b.join(','))+'}';
		return val;
	}
	if (v === null) {
		return 'null';
	}
	if (typeof(v) === 'object' && v.constructor === Array) {
		return fmt_grp(v);
	}
	else {
		return v;
	}
}

function RecEditPanel(rdbAdmin,databaseManager,selectPanel)
{
	this.rdbAdmin = rdbAdmin;
	this.dbMgr = databaseManager;
	this.selectPanel = selectPanel;
	this.htmlTableId = 'edit-rec-table';
	this.rownamestem = 'edit-panel-table-tr-';
	this.formId = 'edit-record-panel-form';
	this.tableName = '';
	this.record = null;
	this.header = null;
	this.columns = null;
	this.mode = 'edit';

	this.init_handlers = function () {
		var $this = this;

		// add click handlers to select panel table
		$('#select-panel-new-item').click(function() {
			var hdr = $this.selectPanel.header, tableName = $this.selectPanel.tableName;
			$this.show(null,hdr,tableName,'new');
		});
		$('#edit-panel-save-btn').click(function() { return $this.save(); });
		$('#edit-panel-save-insert-btn').click(function () { return $this.saveAndInsert(); });
		
		// set change-detection on input fields
		$('#edit-rec-table :input').live('change', function() { $this.markChange(this); });
		// setup toggle between text and file inputs
		$('#edit-rec-table button').live('click',function() { $this.textFileToggle(this); });
		// add select panel 'edit' click handlers 
		$('span[id^="sel-table_tr_edit_"]').live('click',function() { $this.showSelectRow(this); });
	};
	
	this.show = function(record, header, tableName, mode)
	{
		this.rdbAdmin.resetMessages(); 
		this.rdbAdmin.showPanel("edit-record-panel");
		this.tableName = tableName;
		this.record = record;
		this.header = header;
		this.mode = mode;
		if (this.mode === 'new') {
			$('#edit-panel-save-inert-btn').css('display','inline');
			this.rdbAdmin.setHeading("New record: " + tableName);
		}
		else {
			$('#edit-panel-save-inert-btn').css('display','none');
			this.rdbAdmin.setHeading("Edit record: " + tableName);
		}
		this.buildTable();
		return true;
	};

	this.showSelectRow = function(elem)
	{
		var $this = this;
		var rI = $(elem).parents('tr:first').get(0).rowIndex;
		var rowIndex = parseInt(rI,10)-1;
		var row = $this.selectPanel.data.rows[rowIndex];
		var head = $this.selectPanel.data.header;
		var tableName = $this.selectPanel.tableName;
		//alert('sel-table_tr_edit');
		$this.show(row,head,tableName,'edit');
	};		

	this.calc_field_size = function(field,maxLen,dType)
	{
		// calc field size
		var len = 0, max, h, h1;
		if ( maxLen ) {
			if ( maxLen<80 ) {
				len = max = maxLen;
			}
			else {
				len = 80;
				max = maxLen;
			}
		}
		else if ( dType === 'boolean' ) {
			len = max = 8;
		}
		else {
			var apiT = apiType(dType);
			if ( apiT === 'NUMBER' ) {
				len = max = 30;
			}
			else if ( $.inArray(apiT,['DATE','TIME','DATETIME'])>-1 ) {
				len = max = 45;
			}
			else if ( field !== '' ) {
				if ( field.length<80 ) {
					len = field.length;
					max = undefined;
				}
				else {
					len = 80;
					max = undefined;
				}
			}
		}
		if ( max !== undefined && max<120 ) {
			//alert('f: '+field+' mL '+maxLen+' dT '+dType+' l '+len+' m '+max);
			return ['t',len,max];
		}
		else {
			len = 80;
			if ( max !== undefined ) {
				h = Math.floor(max/len);
				if ( h>4 ) { h = 4; }
			}
			else {
				h = 4;
			}
			// if field data is larger 
			if ( field && field.length ) {
				if ( field.length > 80*4 ) {
					h1 = Math.floor(field.length/len);
					if (h1>4) {
						if (h1 <= 6) { h = h1; }
						else {
							h = Math.floor(6+(h1-6)/1.5);
							if (h>20) { h = 20; }
						}
					}
				}
			}
			return ['a',h,len,max];
		}
	};

	this.buildTable = function()
	{
		var $txtarea, $this = this;
		// manipulate html table
		var $table = $('#'+this.htmlTableId);
		var $row = $table.find('tr:first').show().remove();
		// clear table, and save source row for future use. hide it.
		$table.empty().append($row.hide());
		function recedit(json) {
			$this.columns = json.fields;
			if ($this.columns !== false) {
				// create html table: render fields and data
				for ( var i=0; i<$this.columns.length; i+=1 ) {
					var col = $this.columns[i];
					var field = '';
					if ($this.record) {
						field = fmt($this.record[i]);
					}
					var fldqual = $this.calc_field_size(field,col.maxLength,col.dataType);
					var $newrow = $row.clone().show();
					$newrow.attr('id',$this.rownamestem+i);
					$newrow.find('#colname').html(col.columnName).attr('id','colname'+i);
					if (fldqual[0] === 't') {
						$newrow.find('#colval_text').val(field).attr('id','colval_text'+i);
						$newrow.find('#colval_text'+i).attr('size',fldqual[1])
													 .attr('maxlength',fldqual[2]);
					}
					else {
						$txtarea = $('<textarea />').attr('id','colval_text'+i);
						$txtarea.attr('rows',fldqual[1]).attr('cols',fldqual[2]);
						if (fldqual[3] !== undefined) {
							$txtarea.attr('maxlength',fldqual[3]);
						}
						$txtarea.val(field);
						$newrow.find('#colval_text').after($txtarea);
						$newrow.find('#colval_text').remove();
					}
					$newrow.find('#colval_file').attr('id','colval_file'+i);
					$newrow.find('#colchanged').attr('id','colchanged'+i);
					$newrow.find('#coltype').val(apiType(col.dataType))
										   .attr('id','coltype'+i);
					$table.append($newrow);
				}
			}
		}
		// find field types
		this.dbMgr.getTableDetails(this.tableName,recedit);
	};
	
	//  sets colchanged# field 'yes' if input changes
	this.markChange = function(elem) {
		//var row = $(elem).parent().parent();
		var row = $(elem).parents('tr:first'); //.get(0).rowIndex;
		var idx = row.attr('rowIndex')-1;
		row.find('#colchanged'+idx).val("yes");
	};
	
	// toggle between text and file 
	this.textFileToggle = function(elem) {
		var row = $(elem).parent().parent();
		var idx = row.attr('rowIndex')-1;
		if (row.find('#colval_file'+idx+':visible').length) {
			row.find('#colval_file'+idx).hide();
			row.find('#colval_text'+idx).show();
			row.find('button').html('file');
		}
		else if (row.find('#colval_text'+idx+':visible').length) {
			row.find('#colval_text'+idx).hide();
			row.find('#colval_file'+idx).show();
			row.find('button').html('text');
		}
		else {
			alert('ERROR: no input field visible '+idx+' ');
		}
	};

	this.save = function()
	{
		var $this = this;
		function showSelectPanel() {
			$this.selectPanel.show($this.tableName);
		}
		return this.saveAnd(showSelectPanel);
	};
	
	this.saveAndInsert = function()
	{
		function prepInsertForm() {
			//$('#sel-panel_jush-sql').html('<code>'+queryString+'</code>');			
		}
		return this.saveAnd(prepInsertForm);
	};
	
	this.saveAnd = function(doAfter)
	{
		var $this = this;
		if (doAfter===undefined) {
			doAfter = function () {};
		}
		var success = this.prepFormForSubmit();
		if ( success === false ) {
			return false;
		}
		function callback (data) {
			if (data.status[0] !== 'error')  {
				$this.rdbAdmin.showWorkingMessage(data.row_count[1]);
				// empty fields
				var $table = $('#'+$this.htmlTableId);
				$table.find('input').add('textarea').val('').removeAttr('name');
				doAfter(data);
			} 
			else {
				alert('error wrongly passed to success callback '+str(data.error[1]) );
			}
		}
		// querying
		this.dbMgr.sqlEngine.queryByForm( { 'formId' : this.formId,
										    'callback' : callback,
											'errback' : errback } );
		return true;
	};
	
	this.prepFormForSubmit = function()
	{
		var $this = this;
		var changefields = [];
		var original_vals = [];
		var argctr = 0;
		var $table = $('#'+this.htmlTableId);

		function add_hidden_arg_field(val) {
			var	argnum = 'arg'+('000'+argctr).substr((''+argctr).length);
			argctr += 1;
			var $fld = $('<input type="hidden"  class="to-remove-later" />');
			$fld.attr('name',argnum).val(val);
			$table.append($fld);
		}
		function add_hidden_query_field(q) {
			var $fld = $('<input type="hidden" name="q" class="to-remove-later" />');
			$fld.val(q);
			$table.append($fld);
		}
		var okTypes = ['int','bigint','smallint','integer','serial','bigserial',
					'real','float','double','decimal','double','decimal',
					'number','numeric','text','character','char','varchar',
					'character varying','timestamp','timestamp with time zone',
					'timestamp without time zone','date','time',
					'time with time zone','time without time zone','bytea'];
		// old values here - this.record
		if ( $this.record && $this.record.length ) {
			for ( var ovi=0; ovi<$this.record.length; ovi+=1 ) {
				var ov = $this.record[ovi];
				var ovc = $this.columns[ovi];
				if ( $.inArray(ovc.dataType,okTypes)>-1 ) {
					original_vals.push([ovc.columnName,ov]);
				}
			}
		}
		// new values - in html fields
		//   iterate to put name attributes in changed fields
		$table.find('input[id^="colchanged"]:gt(0)').each(function() {
			if ($(this).val() === 'yes') {
				var $row = $(this).parent().parent();
				var index = $row.attr('rowIndex')-1;
				// ### add null test
				var $cval = $row.find('input[id^="colval_"]:visible');
				$cval = $cval.add($row.find('textarea[id^="colval_"]:visible'));
				if ($cval.length>1) { alert('too many colvals'); }
				var argnum = 'arg'+('000'+argctr).substr((''+argctr).length);
				argctr += 1;
				$cval.attr('name',argnum);
				var $cvaltype = $row.find('input[id^="coltype"]');
				if ($cvaltype.length>1) { alert('too many coltypes'); }
				$cvaltype.attr('name',argnum+'type');
				changefields.push([$this.columns[index].columnName,true]);
			}
		});
		// assemble a query string
		var qnew = []; // field-change parts of query
		var orig = []; // names of fields with orig data to reference
		var qnews, queryRet, f;
		if (changefields.length === 0) {
			alert('no fields were changed!');
			return false;
		}
		if (this.mode === 'edit') {
			for ( f=0; f<changefields.length; f+=1 ) {
				if (changefields[f][1]===null) {
					qnew.push('"'+changefields[f][0]+'" is NULL');
				}
				else {
					qnew.push('"'+changefields[f][0]+'"=%s');
				}
			}
			qnews = qnew.join(',');
			for ( var oid=0; oid<original_vals.length; oid+=1 ) {
				if (original_vals[oid][1] === null) {
					orig.push('"'+original_vals[oid][0]+'" = NULL');
				}
				else {
					orig.push('"'+original_vals[oid][0]+'"=%s');
					add_hidden_arg_field(original_vals[oid][1]);
				}
			}
			var origvals = orig.join(' AND ');
			queryRet = 'UPDATE '+quoteIdentifier($this.tableName)+' SET '+qnews+
					   ' WHERE '+origvals;
		}
		else {
			var tokens = [];
			for ( f=0; f<changefields.length; f+=1 ) {
				if (changefields[f][1]===null) {
					qnew.push('"'+changefields[f][0]+'"');
				}
				else {
					qnew.push('"'+changefields[f][0]+'"');
				}
				tokens.push('%s');
			}
			qnews = qnew.join(',');
			var tkns = tokens.join(',');
			queryRet = 'INSERT INTO '+quoteIdentifier($this.tableName)+' ('+qnews+')'+
			           ' VALUES( ' + tkns + ');';
		}
		// put query into form
		add_hidden_query_field(queryRet);
		return true;
	};
}

//