// variables
var uid=0;
var ulog='guest';
var uname='Guest';
var access=255;

var config=new Array();

// constants
var ACCESS_READ=1;
var ACCESS_VIEW=2;
var ACCESS_ADD=4;
var ACCESS_EDIT=8;
var ACCESS_DELETE=16;
var ACCESS_EXECUTE=32;
var ACCESS_CUSTOM1=64;
var ACCESS_CUSTOM2=128;



String.prototype.capitalize = function(){
   return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } );
  };

Function.prototype.getName= function(){
	var tem= this.toString().match(/function\s+(\w+) *\(/);
	return (tem)? tem[1]: '';
}


function labelAlign() {
	// align label and return maximum length label
	var max = 0;
	$("label").each(function(){
		if ($(this).width() > max)
			max = $(this).width();   
	});
	$("label").width(max);
	return max;
}

function renderData(responseText, statusText)  { 
	for (var key in responseText) {
		if (mode=='view') {
			if(responseText[key]!='')
				$('#'+key).html(responseText[key]);
		} else {
			$('#'+key).val(responseText[key]);
		}
	}	

	for (i=0;i<fieldName.length;i++) {
		switch(fieldType[i]) {
			case 'picture':
			if (mode=='edit') {
				setUploader('#'+fieldName[i]+'Uploader',fieldName[i],'upload'+fieldCaption[i]+'/',$('#'+fieldName[0]).val());
				
				if($('#'+fieldName[i]).val()) $('#'+fieldName[i]).attr('src', 'render'+fieldCaption[i]+'/?id='+$('#'+fieldName[0]).val())
				else $('#'+fieldName[i]).attr('src', '/images/1.gif');
			}
			if (mode=='view') {
				if($('#'+fieldName[i]).html()) $('#'+fieldName[i]).attr('src', 'render'+fieldCaption[i]+'/?id='+$('#'+fieldName[0]).html())
				else $('#'+fieldName[i]).attr('src', '/images/1.gif');
			}
			break;
			case 'choice' :
				//alert(responseText['continent']);
				$('input#continent').val(responseText['continent']);
			break
		}
	}
} 

function FormCtl(cfg) {
	this.config=cfg;
	this.mode='view';
	this.formID='#formData' // id of the form
	this.fieldNames=new Array();
	this.fieldTypes=new Array();
	this.fieldCaptions=new Array();
	this.fieldCases=new Array();
	this.fieldMaxLength=new Array();
	this.fieldMinLength=new Array();
	this.fieldHints=new Array();
	this.fieldForm=new Array();
	
	this.init = function() {
		var tmp;
		
		tmp=new String(this.config.field.name);
		this.fieldNames=tmp.split("\t");

		tmp=new String(this.config.field.type);
		this.fieldTypes=tmp.split("\t");

		tmp=new String(this.config.field.caption);
		this.fieldCaptions=tmp.split("\t");

		tmp=new String(this.config.field.cases);
		this.fieldCases=tmp.split("\t");

		tmp=new String(this.config.field.maxLength);
		this.fieldMaxLength=tmp.split("\t");
		
		tmp=new String(this.config.field.minLength);
		this.fieldMinLength=tmp.split("\t");

		tmp=new String(this.config.field.hint);
		this.fieldHints=tmp.split("\t");
		
		eval('tmp=new String(this.config.form.'+this.mode+');');
		this.fieldForm=tmp.split("\t");

	}
	
	this.render = function() {
		for (i=0;i<this.fieldForm.length;i++) {
			idx=this.fieldNames.indexOf(this.fieldForm[i]);
			if(this.config.table.autonumber && i==0) { // if autonumber exist, first field will be marked hidden
				$('#'+this.formID).append("<div><input type=hidden id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' /></div>");
				continue; // skip processing
			}
		switch(this.fieldTypes[idx]) {
			case 'text':
				if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span  id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+(this.fieldCases[idx]==""?"":" class='"+this.fieldCases[idx]+"'")+"  >-</span></div>");
				else {
					size="";
					
					if ((this.fieldMaxLength[idx]!=0) && (this.fieldMaxLength[idx]<30)) size="size=\""+this.fieldMaxLength[idx]+"\"  maxlength=\""+this.fieldMaxLength[idx]+"\"";

					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><input id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' "+size+(this.fieldCases[idx]==""?"":" class='"+this.fieldCases[idx]+"'")+"  /></div>");	
				}					
				break;
			case 'password':
				if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>");
				else {
					size="";
					if ((this.fieldMaxLength[idx]!=0) && (this.fieldMaxLength[idx]<30)) size="size="+this.fieldMaxLength[idx]+" maxlength="+this.fieldMaxLength[idx];
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><input type=password id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' "+size+"  /></div>");
				}
				break;
			case 'number':
				// TODO: update require (still tempated from text')
				size="";
				if (this.fieldMaxLength[idx]!=0) size="size="+this.fieldMaxLength[idx]+" maxlength="+this.fieldMaxLength[idx];
				if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>");
				else
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><input id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' "+size+" class='inplaceeditor' /></div>");					
				break;
			case 'multitext':
				if (this.mode=='view') 
					$('#'+this.formID).append("<fieldset><legend>"+this.fieldCaptions[idx]+"</legend><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></fieldset>");
				else 
					$('#'+this.formID).append("<fieldset><legend>"+this.fieldCaptions[idx]+"</legend><textarea id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' cols=40 ></textarea></fieldset>");
					
				//$('textarea').elastic();
				break;
			case 'choice':
				if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>");
				else {
					//choice=responseText[];
					eval("choice=this.config.choice."+this.fieldNames[idx]+";");
					choices=choice.split("\t");
					for(j=0;j<choices.length;j++) {
						choices[j]=" <input type=radio id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' value='"+choices[j]+"' />"+choices[j];
					}
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label>"+choices.join(" ")+"</div>");
				}
				break;
			case 'lookup':
				if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>");
				else 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><select id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' "+size+" ></select></div>");
				break;
			
			case 'date':
					
				if (this.mode=='view') {
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>")
				} else {
					size="10";
					
					if (this.fieldMaxLength[idx]!=0) size="size="+this.fieldMaxLength[idx]+" maxlength="+this.fieldMaxLength[idx];
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><input id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"' "+size+" /></div>");
					$('#'+this.fieldNames[idx]).datepicker();
				}
				break;
			case 'file': // under construction
				break;
			case 'picture':
				if(this.mode=='add') continue;
				
				if(this.mode=='view') {
					$('#'+this.formID).append('<fieldset><legend>'+this.fieldCaptions[idx]+'</legend><img id="'+this.fieldNames[idx]+'" name="'+this.fieldNames[idx]+'" src="/images/1.gif" /></fieldset>');
				} else {
					$('#'+this.formID).append('<fieldset><legend>'+this.fieldCaptions[idx]+'</legend><span id="'+this.fieldNames[idx]+'Uploader" name="'+this.fieldNames[idx]+'Uploader" ><img id="'+this.fieldNames[idx]+'" name="'+this.fieldNames[idx]+'"  src="/images/1.gif" /><br />upload</span></fieldset>');
				}
				break;
			default:
			if (this.mode=='view') 
					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><span id="+this.fieldNames[idx]+" name="+this.fieldNames[idx]+"  >-</span></div>");
				else {

					$('#'+this.formID).append("<div><label>"+this.fieldCaptions[idx]+"</label><input id='"+this.fieldNames[idx]+"' name='"+this.fieldNames[idx]+"'  /></div>");	
				}	
				
		}
	};
	}
	
	this.align = function() {
		var max = 0;
		$("label").each(function(){
			if ($(this).width() > max)
				max = $(this).width();   
		});
		$("label").width(max);
	}
	
	this.loadData = function() {
		var md=this.mode;
		 $.fTypes=this.fieldTypes;
		 $.fNames=this.fieldNames;
		 $.fCaptions=this.fieldCaptions;
		$.post("getRecord/",window.location.search.substring(1),function(record,testStatus) {
			switch(md) {
				case 'view':
					for(var propertyName in record) {
						if($("#"+propertyName)==null) continue;
						if(record[propertyName]) $("#"+propertyName).html(record[propertyName].replace(/\n/g,"<br />"));
					}
					for(i=0;i<$.fTypes.length;i++) {
						switch($.fTypes[i]) {
							case 'picture':
								$("#"+$.fNames[i]).attr("src", "render"+$.fCaptions[i]+"/?id="+$("#"+$.fNames[0]).html());
								break;
						}
					}
					break;
				case 'edit':
					for(var propertyName in record) {
						if($("#"+propertyName)==null) continue;
						$("#"+propertyName).val(record[propertyName]);
						
					}
					for(i=0;i<$.fTypes.length;i++) {
						switch($.fTypes[i]) {
							case 'picture':
								$.i=i;
								$("#"+$.fNames[$.i]).attr("src", "render"+$.fCaptions[$.i]+"/?id="+$("#"+$.fNames[0]).val());


								new AjaxUpload("#"+$.fNames[i]+"Uploader", {
								  action: "upload"+$.fCaptions[i]+"/",
								  name: $.fNames[i],
								  data: {
									id : $("#"+$.fNames[0]).val()
								  },
								  onSubmit : function(file , ext){
											var message=new MessageCtl(this.config);
												if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
													message.warn("Error: invalid file extension");
													return false;
												}
									},
									onComplete: function(file, response) {
											var message=new MessageCtl(this.config);
											
											if(response!='') {
												message.warn(response);
											} else {
												message.notify("success upload "+file);
											}
											$("#"+$.fNames[$.i]).attr("src", "render"+$.fCaptions[$.i]+"/?id="+$("#"+$.fNames[0]).val()+"&key="+Math.random());
									
										}

								});

								break;
						}
					}
					break;
				case 'add':
					break;
					
			}

		},"json" );	

	}
	
	this.loadControl=function() {
		switch(this.mode) {
			case 'add':
				if(access&ACCESS_ADD==ACCESS_ADD) {
					$('#btnSave').css("display","inline");
					$('#btnSaveClose').css("display","inline");
				} else {
					$('#btnSave').css("display","none")
					$('#btnSaveClose').css("display","none")
				}
				
				break;
			case 'view':
				$('#btnEdit').css("display",(access&ACCESS_EDIT==ACCESS_EDIT)?"inline":"none");
				$('#btnDelete').css("display",(access&ACCESS_DELETE==ACCESS_DELETE)?"inline":"none");
				break;
			case 'edit':
				$('#btnUpdate').css("display",(access&ACCESS_EDIT==ACCESS_EDIT)?"inline":"none");
				$('#btnDelete').css("display",(access&ACCESS_DELETE==ACCESS_DELETE)?"inline":"none");
				
				break;
		}
	}
	
	this.addRecord=function(url) {
		$.url=url;
		if(!confirm('You are submitting new data. \nContinue?'))  return false;
		
		$.post("add/",$("form").serialize(), function(responseData, textStatus) {
			message=new MessageCtl();
			
			if (responseData!="") {
				message.warn(responseData);
			} else {
				message.notify("success submitting data");
				if($.url) $(location).attr('href',$.url);
			}
		});
	}
	
	this.updateRecord=function() {
		if(!confirm('You are updating data. \nContinue?'))  return false;
		
		$.post("update/",$("form").serialize(), function(responseData, textStatus) {
			message=new MessageCtl();
			if (responseData!="") {
				message.warn(responseData);
			} else {
				message.notify("success updating data");
				
			}
		});
	}
	
	this.deleteRecord=function(id, url) {
		if(!confirm('You are deleting data. \nContinue?'))  return false;
		$.url=url;
		
		$.post("delete/",{'id':id}, function(responseData, textStatus) {
			message=new MessageCtl();
			if (responseData!="") {
				message.warn(responseData);
			} else {
				message.notify("success deleting data");
				if($.url) $(location).attr('href',$.url);
			}
		});
	}
	
}

// In Page Message Controller

function MessageCtl() {
	// requires div id names "message" 
	this.clear = function() {
		if($("#message")) {
			$("#message").fadeOut(2000);
			if($("#message").hasClass("ui-state-highlight")) $("#message").removeClass("ui-state-highlight")
			if($("#message").hasClass("ui-state-error")) $("#message").removeClass("ui-state-error")
		 } else {
			alert('no in-page message support. contact administrator');
		 }
	}
	
	this.warn = function(msg) {
		if($("#message")) {
			$("#message").html(msg);
			$("#message").show();
			if($("#message").hasClass("ui-state-highlight")) $("#message").removeClass("ui-state-highlight")
			if(!$("#message").hasClass("ui-state-error")) $("#message").addClass("ui-state-error")
		} else {
			alert('no in-page message support. contact administrator');
		}
	}
	
	this.notify = function (msg) {
		// it is assumed that class of ui-state-highlight not applied together with ui-state-error
		if(!$("#message")) {
			alert('no in-page message support. contact developer');
			return false;
		}
		
		$("#message").html(msg);
		if(!$("#message").hasClass("ui-state-highlight")) $("#message").addClass("ui-state-highlight")
		if($("#message").hasClass("ui-state-error")) $("#message").removeClass("ui-state-error")
		$("#message").show();
	}

}

// List Data Controller

function DataCtl(cfg) {
//  class to bind table with php based database
	this.pageNumber=1;
	this.pageSize=10;
	this.pageLast=1000;
	this.rowStart=0;
	this.sortBy='timestamp_update';
	this.sortOrder='desc';
	this.url='getData/';
	this.config=cfg; // refers to global configuration
	this.tableID=''; // refers to table ID in html page
	this.viewID='all'; // refers to views ID in configuration
	this.varID=''; //refers to variable instance calling this object, used for calling method on rendering
	this.isNumbered=true; // add numbering column
	this.fieldFocus='';// name of field having linked to view menu
	
	this.setPageSize = function(id) {
		this.pageSize=id;this.pageNumber=1;this.rowStart=0;
		this.refresh();
	}
	
	this.setOrder = function(id) {
		if(this.sortBy==id) {
			this.sortOrder=(this.sortOrder=='asc')?'desc':'asc';
		} else {
			this.sortBy=id;
			this.sortOrder='asc';
		}
		this.refresh();
	}

	this.setPage = function(id) {
		switch(id) {
		case 'first':
			this.pageNumber=1;
			this.rowStart=0;
			break;
		case 'prev':
			this.pageNumber=(this.pageNumber>0)?this.pageNumber-1:this.pageNumber;
			this.rowStart=(this.pageNumber-1)*this.pageSize;
			break;
		case 'next':
			this.pageNumber=(this.pageNumber<this.pageLast)?this.pageNumber+1:this.pageNumber;
			this.rowStart=(this.pageNumber-1)*this.pageSize;
			break;
		case 'last':
			this.pageNumber=this.pageLast;
			this.rowStart=(this.pageNumber-1)*this.pageSize;
			break;
		}
		this.refresh();
	}

	this.refresh = function() {
		$.thisForm=this;
		$.pageSize=this.pageSize;
		$.pageNumber=this.pageNumber;
		$.post(this.url,{'sortBy':this.sortBy, 'sortOrder':this.sortOrder,'pageNumber':this.pageNumber, 'pageSize':this.pageSize}, function(responseData, textStatus) {
			$.thisForm.renderBody(responseData);
			$.thisForm.renderHeader();
			$.thisForm.renderFooter();
			
			$('#pageNumber').html($.pageNumber);
			
			$('#cmbPageSize').val($.pageSize);

		},"json");
			
	} 
	
	this.renderHeader = function() {
		names=new String(this.config.field.name);
		types=new String(this.config.field.type);
		captions=new String(this.config.field.caption);
		
		fieldView=new Array();
		fieldName=names.split("\t");
		fieldType=types.split("\t");
		fieldCaption=captions.split("\t");
		
		eval("views=this.config.view."+this.viewID);
		fieldView=views.split("\t");
		result=(!this.isNumbered)?"":"<th>No</th>";
		for(i=0;i<fieldView.length;i++) {
			idx=fieldName.indexOf(fieldView[i]);
			
			result+="<th><a href=# onclick=\""+this.varID+".setOrder('"+fieldName[idx]+"');return false;\">"+fieldCaption[idx]+"</a></th>";
		}

		$("#"+this.tableID+" > thead").empty();
		$("#"+this.tableID+" > thead").append("<tr>"+result+"</tr>");
	}
	
	this.renderBody = function(data) {
		var str=new String();
		names=new String(this.config.field.name);
		types=new String(this.config.field.type);
		captions=new String(this.config.field.caption);
		
		this.pageLast=Math.ceil(parseInt(data.numRecords)/this.pageSize);
		var data=data.data;
			
			
		fieldView=new Array();
		fieldName=names.split("\t");
		fieldType=types.split("\t");
		fieldCaption=captions.split("\t");
		
		eval("views=this.config.view."+this.viewID);
		fieldView=views.split("\t");
		
		result="";
		
		for(r=0;r<data.length;r++) {
			result+="<tr>";
			if(this.isNumbered) result+="<td class=number>"+(this.rowStart+r+1)+"</td>"; 
			eval("id=data[r]."+fieldName[0]+";"); // first field always PK
			
			for(i=0;i<fieldView.length;i++) {
				eval("str=data[r]."+fieldView[i]+";");
				
				idx=fieldName.indexOf(fieldView[i]); // set class based on type
				typ=fieldType[idx];
				
				if((this.fieldFocus!='') && (this.fieldFocus==fieldView[i]))
					result+="<td class=\""+typ+"\"><a href='view.html?id="+id+"'>"+str.replace(/\n/g,"<br />")+"</a></td>";
				else
					result+="<td class=\""+typ+"\">"+str.replace(/\n/g,"<br />")+"</td>";
			}
			result+="</tr>";
		}
		$("#"+this.tableID+" > tbody").empty();
		$("#"+this.tableID+" > tbody").append("<tr>"+result+"</tr>");

	}
	
	this.renderFooter = function() {
		cfg=this.config; // read config from global variable
		eval("views=cfg.view."+this.viewID);
		fieldView=views.split("\t");
		colspan=fieldView.length;
		if(this.isNumbered) colspan++;
		$("#"+this.tableID+" > tfoot").empty();
		$("#"+this.tableID+" > tfoot").append("<tr ><th colspan="+colspan+"><div style=\"float:left\"><a href=# onClick=\""+this.varID+".refresh();return false\"><img border=0 src='refresh.png'></a></div><div style=\"float:right\"><select id=cmbPageSize onchange=\""+this.varID+".setPageSize(this.value);\"><option value=10>10</option><option value=20>20</option><option value=50>50</option><option value=100>100</option></select></div>"+(this.pageNumber==1?"":"<a href=# onClick=\""+this.varID+".setPage('first');return false;\"><img border=0 src='first.gif'></a> <a href=# onClick=\""+this.varID+".setPage('prev');return false\"><img border=0 src='prev.gif'></a>")+" [<span id=pageNumber></span>] "+(this.pageNumber==this.pageLast?"":"<a href=# onClick=\""+this.varID+".setPage('next');return false\"><img border=0 src='next.gif'></a> <a href=# onClick=\""+this.varID+".setPage('last');return false\"><img border=0 src='last.gif'></a>")+"</th></tr>");

	}

	

}

  



/*OBSOLETE FOR JQUERY ERA */
function readParameters() {
	var qsParm = new Array();
	var query = window.location.search.substring(1);
	var parms = query.split('&');
	for (var i=0; i<parms.length; i++) {
		var pos = parms[i].indexOf('=');
		if (pos > 0) {
			var key = parms[i].substring(0,pos);
			var val = parms[i].substring(pos+1);
			qsParm[key] = val;
		}
	}
	return qsParm;
}
