pcwa.core.scope('pcwa.ext.view');

pcwa.ext.view.DataForm = function DataForm(config){
	pcwa.ext.view.DataForm.superclass.constructor.call(this, config);
	
	this.config = config;
	this.location = "";
	this.lastUpdateOp = '';
	this.data = null;
	this.dataBound = false;
					
	if ( !config.focusField){ config.focusField = "";}
	if (  config.focusOnLoad == undefined || config.focusOnLoad == null ){ config.focusOnLoad = true;}
	if ( !config.checkboxValues ) { config.checkboxValues = {}; }
	if ( !config.checkboxValues.defaults ) { config.checkboxValues.defaults = {checked: 'Y', unchecked: 'N'}; }
	
	if ( config.data ){ this.setData(config.data); }

	this.addEvents(
		/**
		 * Column Level Events
		 */
		'beforechange',
		'change',
		'cancel',
		/**
		 * Record Level Events
		 */
		'load',
		'update'
	);
};

Ext.extend( pcwa.ext.view.DataForm, Ext.form.FormPanel,
{
	bindFields: function bindFields(){
		if ( !this.dataBound ){
			var items = this.getForm().items;
			var cnt = items.getCount();
			var field = null;
			
			for ( var i = 0; i < cnt; i++ ){
				field = items.get(i);
				if ( field.getXTypes().match(/combo/i) != null ){
					field.on({
						select:	function(fld, rec, index){
									if ( this.queryFieldChange(fld, fld.getValue(),
											this.data.record.get(fld.initialConfig.name)) )
									{
										this.data.record.set(fld.initialConfig.name, fld.getValue());
										this.notifyFieldChange(fld, fld.getValue());
									}else{
										fld.setValue(this.data.record.get(fld.initialConfig.name));
										fld.focus(true, true);
									}
								},
						scope:	this
					})
				} else if ( field.getXTypes().match(/checkbox/i) != null ){
					field.on({
						check:	function(fld, status){
									var values = this.getCheckboxValues(fld.getName());
									var oldVal = this.data.record.get(fld.getName());
									var newVal = status ? values.checked : values.unchecked;
									
									if ( this.queryFieldChange(fld, newVal, oldVal) ){
										this.data.record.set(fld.getName(), newVal);
										this.notifyFieldChange(fld, newVal);
									}else{
										if ( this.data.record.get(field.getName()) == values.checked ){
											fld.setValue('on');
										}
										fld.focus(true, true);
									}
								},
						scope:	this
					});
				} else {
					field.on({
						change:	function(fld, newVal, oldVal){
									if ( this.queryFieldChange(fld, newVal, oldVal) ){
										this.data.record.set(fld.getName(), newVal);
										this.notifyFieldChange(fld, newVal);
									}else{
										fld.setValue(oldVal);
										fld.focus(true, true);
									}
								},
						scope:	this
					});
				}
			}
			this.dataBound = true;
		}
	},
	clearData:			function clearData(){
							if ( this.data ){
								this.getForm().reset();
								Ext.StoreMgr.remove(this.data.store);
								delete this.data.store;
								delete this.data.origStore;
								if ( this.data.newRecord ){
									delete this.data.newRecord;
								}else{
									delete this.data.record;
								}
								if ( this.data.evtParams ){
									delete this.data.evtParams;
								}
								delete this.data;
							}
						},
	copyRecord:			function copyRecord(rec){
							var r = rec.copy();
							if ( rec.modified != null ){
								r.modified = Ext.apply({}, rec.modified);
								r.dirty = rec.dirty;
							}
							return r;
						},
	copyStores:			function copyStores(){
							this.data.origStore = this.data.store;
							var url = this.data.origStore.proxy.conn.url;
							if ( !this.data.newRecord ){
								if ( url.substr(url.lastIndexOf('/') + 1) != this.data.record.get(this.data.record.store.id))  {
									url += "/" + this.data.record.get(this.data.record.store.id);
								}
							}
							this.data.store = new pcwa.ext.model.JsonStore({
								url:		url,
								root:		this.data.origStore.root,
								id:			this.data.origStore.id,
								storeId:	Ext.id('', 'dataform-' + this.data.origStore.storeId + '-'),
								fields:		this.data.origStore.reader.meta.fields
							});
							this.data.store.reader.meta.etagField = this.data.origStore.reader.meta.etagField;
						},
	destroy:			function destroy(){
							this.clearData();
							pcwa.ext.view.DataForm.superclass.destroy.call(this);
						},
	getCheckboxValues:	function getCheckboxValues(fldName){
							return typeof this.config.checkboxValues[fldName] == 'undefined'
								? this.config.checkboxValues.defaults
								: this.config.checkboxValues[fldName];
						},
	getFieldValue:		function getFieldValue(fldName){return this.data.record.get(fldName);},
	getFocusField:		function getFocusField(){ return this.config.focusField;},
	getRecord:			function getRecord(){ return this.copyRecord(this.data.record);},
	getStore:			function getStore(){ return this.data.store;},
	isDirty:			function isDirty(){	return this.data.store.getModifiedRecords().length > 0;},
	loadData:			function loadData(){
							if ( !this.data.newRecord ){
								this.data.store.add([this.copyRecord(this.data.record)]);
							} else {
								this.data.store.add([this.copyRecord(this.data.newRecord)]);
							}
							this.data.record = this.data.store.getAt(0);
							this.data.store.commitChanges();
							this.setFormData();
							this.bindFields();
							if ( this.config.focusField.length > 0 && this.config.focusOnLoad === true ){
								this.setFieldFocus(this.config.focusField);
							}
							this.fireEvent('load', this, this.copyRecord(this.data.record), this.data.origStore);
						},
	notifyFieldChange:	function notifyFieldChange(fld, newVal){
							this.fireEvent('change', fld, newVal,
											this.copyRecord(this.data.record),
											this.data.origStore);
						},
	processUpdate:		function processUpdate(success, resp, params, errors){
							if ( success ){
								if ( this.data.newRecord && this.location.length == 0 ){
									this.data.store.proxy.conn.url = resp.getResponseHeader("location");
								}
								var rec = this.copyRecord(this.data.record);
								this.data.store.commitChanges();
								this.fireEvent('update', rec, this.data.origStore, this.lastUpdateOp, params);
							} else {
								dataUpdateManager.showErrors(errors, this.getEl());
							}
						},
	queryFieldChange:	function queryFieldChange(fld, newVal, oldVal){
							var retVal = this.fireEvent('beforechange', fld, newVal, oldVal);
							if ( !retVal ){
								this.fireEvent('cancel', fld, this.copyRecord(this.data.record), this.data.origStore);
								retVal = false;
							}
							return retVal;
						},
	reset:				function reset(){
							this.data.store.rejectChanges();
							this.setFormData();
						},
	setData:			function setData(d){
							this.getForm().reset();
							this.clearData();
							this.data = d;
							if ( this.data.record && this.data.newRecord ){ delete this.data.newRecord;}
							if ( this.data.store ){ this.copyStores();}
							if ( this.rendered ){ this.loadData();}
							return this;
						},
	setFieldFocus:		function setFieldFocus(fldName){
							if ( fldName != '' ){
								var fld = this.getForm().findField(fldName);
								if ( fld ) { fld.focus(true, true); }
							}
						},
	setFieldValue:		function getFieldValue(fldName, fldValue){
							this.data.record.set(fldName, fldValue);							
							var items = this.getForm().items;
							var cnt = items.getCount();
							var field = null;
							
							for ( var i = 0; i < cnt; i++ ){
								field = items.get(i);
								if(field.name == fldName){
									field.setValue(fldValue);
								}								
							}
						},	
	setFormData:		function setFormData(){
							var items = this.getForm().items;
							var cnt = items.getCount();
							var field = null, values = null;
							
							if ( this.data.record ){
								this.getForm().loadRecord(this.data.record);
								for ( var i = 0; i < cnt; i++ ){
									field = items.get(i);
									if ( field.getXTypes().match(/checkbox/i) != null ){
										values = this.getCheckboxValues(field.getName());
										if ( this.data.record.get(field.getName()) == values.checked ){
											field.setValue('on');
										}else{
											field.setValue('off');
										}
									}
								}
							}
						},
	update:				function update(evtParams){
							this.data.evtParams = evtParams;
							this.updateProc();
						},
	updateProc:			function updateProc(){
							this.lastUpdateOp = this.data.newRecord && this.location.length == 0
												? 'insert' : 'update';
							
							dataUpdateManager.updateRecord	({
																record:			this.data.record,
																reset:			false,
																callback:		this.processUpdate,
																params:			this.data.evtParams,
																scope:			this
															});
						}
});

