/*
	eTraxx javascript utilities
*/

App =
{
	name: 'eTraxx',
	timeoutUrl: '',

	timeoutFunction: function()
	{
		if (App.timeoutUrl)
			window.location = App.timeoutUrl;
	}
};

/*
	Gecko has an off-by-one bug in measuring text
	that causes unexpected text wrap. This fixes it.
*/
var fixGeckoTipWidth = function(event, api)
{
	if (api.geckoFixed)
		return;

	var tooltip = api.elements.tooltip,
		width = tooltip.width();

	tooltip.width(width + 1);
	api.geckoFixed = true;
};

etraxx =
{
	fieldAutoCreate: { tag: 'input', type: 'text', size: '20', autocomplete: 'off' },

	fieldTipDefaults: {
		overwrite: false,
		position: {
			my: 'left center',
			at: 'right center'
		},
		show: {
			event: false,
			ready: true
		},
		hide: false,
		style: 'ui-tooltip-dark ui-tooltip-jtools ui-tooltip-rounded field-tooltip',
		events: {
			show: Ext.isGecko ? fixGeckoTipWidth : null
		}
	},

	// Setup a custom field marking method
	myMessageTarget : {
		mark: function(field, msg)
		{
			var el = field.getEl(),
				domField = $(el.dom),
				config = Ext.apply({}, field.qtipConfig,
					{
						content: msg || field.invalidText,
					});

			domField.qtip(config).show();

			el.addClass(field.invalidClass);
			el.removeClass(['x-form-valid', 'x-form-needs-validation']);
		},

		clear: function(field)
		{
			field.getEl().addClass('x-form-valid');
			field.getEl().removeClass('x-form-needs-validation');
			(function() { $(field.getEl().dom).qtip('destroy'); }).defer(1);
		}
	},

	makeFormFields: function()
	{
		Ext.form.MessageTargets['my-target'] = etraxx.myMessageTarget;

		// Find all inputs with a data-ext attribute, convert their config to an Ext.form.Field config
		var fields = Ext.query('input[data-ext-field]');

		for (var i = 0; i < fields.length; ++i)
		{
			var domField = fields[i],
				field = Ext.get(domField),
				config = Ext.decode(field.getAttribute('data-ext-field') || '{}');

			if (config.maskRe)
				config.maskRe = new RegExp(config.maskRe);

			var extField = null,
				type = field.getAttribute('type');

			switch (type)
			{
				case 'text':
				case 'password':
				{
					var value = field.getAttribute('value') || '';
						
					if (type === 'password' && config.allowBlank === undefined)
						config.allowBlank = false;
						
					Ext.apply(config,
					{
						name: field.getAttribute('name'),
						id: domField.id,
						inputType: type,
						applyTo: domField,
						hideLabel: true,
						autoHeight: true,
						msgTarget: 'my-target',
						value: value,
						validationEvent: false,
						preventMark: true,
						needsValidation: config.needsValidation || config.allowBlank === false,
						stripCharsRe: config.stripCharsRe || Ext.ux.Util.trimRe,
						originalValue: value,	 // The Ext.form.TextField constructor is not setting this
						listeners:
						{
							'valid': etraxx.onValidField,
							'invalid': etraxx.onInvalidField,
							'blur': etraxx.onBlurField
						}
					});

					if (config.value === '' && config.needsValidation)
						config.cls = 'x-form-needs-validation';
					
					if (config.needsValidation)
					{
						config.qtipConfig = Ext.apply({}, config.qtipConfig, etraxx.fieldTipDefaults);
						
						if (!config.invalidText && !config.vtype)
							config.invalidText = config.allowBlank ? '' : locale.string('text.required-field.js');
					}
						
					extField = new Ext.form.TextField(config);
					
					if (value)
						etraxx.validateField(extField);
					break;
				}
			}

			if (!extField)
				continue;

			// Stash the Field in the form for later reference
			if (extField.needsValidation)
				etraxx.pushFormComponent(extField);
				
			domField.removeAttribute('data-ext-field');
		}
	},

	makeButtons: function()
	{
		var buttons = Ext.query('div[data-ext-button]');

		for (var i = 0; i < buttons.length; ++i)
		{			 
			var placeholder = buttons[i],
				title = placeholder.getAttribute('title'),
				placeholderEl = Ext.fly(placeholder),
				config = Ext.decode(placeholderEl.getAttribute('data-ext-button') || '{}'),
				isSubmit = /^(submit|cancel)$/i.test(config.buttonType),
				name = placeholder.id,
				onclickHandler = placeholder.onclick;

			// We are going to give the placeholder's id to the Button component
			placeholder.id = '_' + name;
			placeholder.innerHTML = '';
			placeholder.onclick = null;

			// Move any click handler to the created button
			var extButton = new Ext.Button(Ext.apply( 
				{
					id: name,
					renderTo: placeholder,
					text: title,
					scale: 'medium',
					ctCls: 'ext-button',
					type: isSubmit ? 'submit' : 'button',
					handler: isSubmit ? etraxx.submitForm : onclickHandler
				}, config));
				
			extButton.btnEl.set({'name':name, 'value':'1'});
			placeholder.removeAttribute('data-ext-button');
			
			// Add it to the form's list of elements to be validated if necessary
			if (config.validator)
			{
				extButton.container.addClass('shrink-to-fit');
				etraxx.pushFormComponent(extButton);
				Ext.override(Ext.Button,
				{
					 isValid: function() { return this.validator(); }
				});
				
				var valid = config.validator.apply(extButton),
					validClass;
				
				if (valid === true)
					validClass = 'valid';
				else if (valid === false)
					validClass = 'invalid'
				else
					validClass = 'needs-validation';
				
				extButton.container.addClass('x-form-' + validClass);
			}
		}
	},
	
	pushFormComponent: function(comp)
	{
		var form = etraxx.getComponentForm(comp);
		
		if (form.extComponents === undefined)
		{
			form.extComponents = [];
			form.onsubmit = etraxx.onSubmitForm;
		}

		form.extComponents.push(comp);
	},
	
	getComponentForm: function(comp)
	{
		var dom = null;
		
		switch (comp.getXType())
		{
			case 'button':
				dom = comp.btnEl.dom;
				break;
				
			default:
				dom = comp.getEl().dom;
				break;
		}
		
		return dom.form;
	},
	
	getFormButton: function(comp)
	{
		var form = etraxx.getComponentForm(comp);
		
		return (form && form['form-button']) ? form['form-button'].value : '';
	},

	initQuickTips: function()
	{
		Ext.QuickTips.init();
	},

	onBlurField: function(field)
	{
		etraxx.validateField(field);
	},

	validateField: function(field)
	{
		if (field.needsValidation)
		{
			field.preventMark = false;
			field.validate();
			field.preventMark = true;
		}
	},
	
	onValidField: function(field)
	{
	},
	
	updateToolbar: function(obj)
	{ 
		var upd = false;
		if (obj.email) {
			emailEl = Ext.get("btn_email");
			if (emailEl) {
				obj.bottomToolbar.add('-')
				obj.bottomToolbar.add(etraxx.onOpenLocation(emailEl.dom.value,emailEl.dom.title,'icon-email'))
				upd = true
			};
		};
		if (obj.pdf) {
			pdfEl = Ext.get("btn_pdf");
			if (pdfEl) {
				obj.bottomToolbar.add('-')
				obj.bottomToolbar.add(etraxx.onOpenWindow(pdfEl.dom.value,pdfEl.dom.title,'icon-pdf'))
				upd = true
			};
		};
		if (upd) {
			obj.show();
			//obj.update(response.responseText, false, etraxx.makeButtons)
		};
	},
	
	datePicker: function(name,id,value,opt){
		if (!opt) {opt = {}};
		dp = new Ext.form.DateField(
			 {
				renderTo: id,
				editable: false,
				showToday: false,
				value: value ? value : '',
				allowBlank: opt["allowBlank"] === false ? false : true,
				name: name,
				format: Ext.DatePicker.prototype.format.replace('y', 'Y')
			 });
	},
	
	showAllButton: function(){
		var el = $("table.search input:text")
		var si = ""
		for (var i=0; i < el.size(); i++) {
			si += el[i].value;
		};
		el = $("table.search select.showall")
		for (var i=0; i < el.size(); i++) {
			si += el[i].value;
		};
		
		if (!si) {
			$("#search-all").attr('style','display:none')

		}else{
			$("#search-all").attr('style','display:inline')
		};

	},
	
	onOpenWindow: function(buttonName,url,icon){
		btn = {
			text: buttonName,
			scale: 'small',
			handler: function(){
				window.open( url ,'mywindow','width=800,height=800,resizeable=yes')
			}
		};
		if (icon) {btn.iconCls = icon};
		return btn
	},
	
	onOpenLocation: function(buttonName,url,icon){
		btn = {
			text: buttonName,
			scale: 'small',
			handler: function(){
				window.location =	 url;
			}
		};
		if (icon) {btn.iconCls = icon};
		return btn
	},
	onConfirmLocation: function(buttonName,url,icon){
		btn = {
			text: buttonName,
			scale: 'small',
			handler: function(){
				if (confirm("Are you sure?")) {
					window.location =	 url;
				};
			}
		};
		if (icon) {btn.iconCls = icon};
		return btn
	},
	
	
	onPrintView: function(id){
		
		return {
			text: 'Printer View',
			iconCls: 'icon-printer',
			scale: 'small',
			handler: function(){
				window.open( urls['print'] + '?id=' + id ,'mywindow','width=800,height=800,resizeable=yes')
			}
		};
		
	},
	
	onInvalidField: function(field)
	{
	},

	submitForm: function(button)
	{
		var form = button.btnEl.dom.form,
			formButton = form['form-button'];

		if (formButton === undefined)
			formButton = Ext.DomHelper.insertFirst(form, {tag:'input', type:'hidden', name:'form-button', id:'form-button'})
			
		formButton.value = button.id;

		if (button.buttonType === 'cancel' || etraxx.onSubmitForm.apply(form))
			form.submit();
	},

	onSubmitForm: function()
	{
		if (this.extComponents) {
			for (var i = 0; i < this.extComponents.length; ++i)
			{
				if (!this.extComponents[i].isValid())
				{
					this.extComponents[i].focus(true, 100);
					return false;
				}
			};
		};
		return true;
	},

	setText: function(element, text)
	{
		element = Ext.getDom(element);

		if (typeof(element.textContent) === 'string')
			element.textContent = text;
		else
			element.innerText = text;
	},

	focusFirstField: function(form)
	{
		if (!form)
			form = document.forms.length ? document.forms[0] : null;

		if (form)
		{
			for (var i = 0; i < form.elements.length; ++i)
			{
				if (/^(text|textarea|password)$/.test(form.elements[i].type))
				{
					form.elements[i].focus();
					return;
				}
			}
		}
	},

	resetForm: function(form)
	{
		for (var i = 0; i < form.elements.length; ++i)
		{
			var field = form.elements[i];

			switch (field.type)
			{
				case 'checkbox':
					field.checked = false;
					break;

				case 'hidden':
				case 'password':
				case 'text':
				case 'textarea':
					field.value = '';
					break;

				case 'select-one':
				case 'select-multiple':
					field.selectedIndex = 0;
					break;
			}
		}
	},

	disableButton: function(button)
	{
		button = Ext.get(button);
		button.disabled = true;
		Ext.get(button).addClass('disabled-button');
	},

	enableButton: function(button)
	{
		button = Ext.get(button);
		button.disabled = false;
		Ext.get(button).removeClass('disabled-button');
	},

	booleanColumnRenderer: function(value)
	{
		// We use a zero-width joiner so that we can align the image to the baseline as if there were text there
		if (value)
			return '&#8205;<img src="/images/checkmark.png" width="12" height="12" style="vertical-align:baseline" alt="&bull;"/>';
		else
			return '';
	},

	estimateSearchBy: function()
	{
		var value = Ext.ux.Util.getSelectValue('search_by');

		if (value === 'date-criteria')
		{
			Ext.fly('search-date-criteria').show();
			Ext.fly('search-estimate-number').hide();
		}
		else
		{
			Ext.fly('search-date-criteria').hide();
			Ext.fly('search-estimate-number').show();
		}
	},

	makeCorners: function()
	{
		// Detect if we are on a browser that supports CSS3
		var isCSS3 = !!document.createElement('canvas').getContext;

		if (isCSS3)
			return;

		for (var t = 0; t < document.styleSheets.length; ++t)
		{
			var stylesheet = document.styleSheets[t],
				rules;

			try
			{
				if (stylesheet.imports)
				{
					for (var i = 0; i < stylesheet.imports.length; ++i)
					{
						rules = stylesheet.imports[i].rules;

						for (var j = 0; j < rules.length; ++j)
						{
							var rule = rules[j],
								border = rule.style['border-radius'];

							if (border)
								$(rule.selectorText).corner(border);
						}
					}
				}

				rules = stylesheet.rules;

				for (var i = 0; i < rules.length; ++i)
				{
					var rule = rules[i],
						border = rule.style['border-radius'];

					if (border)
						$(rule.selectorText).corner(border);
				}
			}
			catch (e)
			{
				console.log(e.message);
			}
		}
	},

	onReady: function()
	{
		// giving up on rounded corners on stupid IE8 for now
		//etraxx.makeCorners();

		etraxx.makeFormFields();
		etraxx.makeButtons();
		//etraxx.initQuickTips();
		etraxx.focusFirstField();
	}
};

etraxx.GridList = function(storeConfig, columnConfig, gridConfig, editConfig)
{
	this.editDialog = null;
	this.editConfig = Ext.apply({}, editConfig || {});
	this.editing = false;

	var stdStoreConfig =
	{
		root: 'data',
		totalProperty: 'count',
		remoteSort: true,
		autoDestroy: true,

		listeners:
		{
			exception: Ext.ux.data.handleJsonStoreException
		}
	};


	this.store = new Ext.ux.data.JsonStore(Ext.apply(stdStoreConfig, storeConfig));
	
	this.store.setDefaultSort(storeConfig.defaultSort || 'id', storeConfig.defaultSortDirection || 'asc');

	columnConfig = this.standardColumnConfig(this.store, columnConfig);
	gridConfig = this.standardGridConfig(this.store, columnConfig, gridConfig);
	this.grid = new Ext.grid.GridPanel(gridConfig);
};

Ext.extend(etraxx.GridList, Ext.util.Observable,
{
	updateColumnMenus: function()
	{
		var cm = this.grid.getColumnModel(),
			config = cm.config;

		for (var i = 0; i < config.length; ++i)
			config[i].menuDisabled = true;

		for (var i = 0; i < config.length; ++i)
		{
			if (!config[i].hidden)
			{
				config[i].menuDisabled = false;
				break;
			}
		}

		cm.setConfig(config);
	},

	/*
		config can be an array or an object that is applied to the standard config.
	*/
	standardColumnConfig: function(store, config)
	{
		var stdConfig =
		{
			defaults:
			{
				sortable: true,
				menuDisabled: true
			},

			columns: [],

			listeners:
			{
				columnmoved: function()
				{
					this.updateColumnMenus();
				},

				hiddenchange: function()
				{
					this.updateColumnMenus();
				},

				scope: this
			}
		};

		if (Ext.isArray(config))
			stdConfig.columns = config;
		else
			Ext.apply(stdConfig, config);

		if (stdConfig.defaults.menuDisabled && stdConfig.columns[0].menuDisabled === undefined)
			stdConfig.columns[0].menuDisabled = false;

		for (var i = 0; i < stdConfig.columns.length; ++i)
		{
			var column = stdConfig.columns[i],
				field = store.fields.get(column.dataIndex),
				align = 'left';

			if (field)
			{
				switch (field.type.type)
				{
					case 'int':
					case 'float':
						align = 'right';
						break;

					case 'bool':
						align = 'center';
						column.renderer = etraxx.booleanColumnRenderer;
						break;

					case 'date':
						column.xtype = 'datecolumn';
						column.format = locale.dateFormat();
						break;
				}

				if (!column.align)
					column.align = align;
			}
		}

		return stdConfig;
	},

	standardGridConfig: function(store, columnConfig, gridConfig)
	{
		var stdConfig =
		{
			id: '',
			width: 1000,
			height: 450,
			title: false,
			store: store,
			stateId: gridConfig.stateId ? gridConfig.stateId : (gridConfig.id ? gridConfig.id : ''),
			trackMouseOver: false,
			disableSelection: false,
			enableHdMenu: true,
			enableColumnHide: true,
			enableColumnMove: true,
			columnLines: true,
			stripeRows: true,
			border: true,
			loadMask: true,
			cls: 'x-grid-list',
			renderTo: 'grid',
			colModel: new Ext.grid.ColumnModel(columnConfig),

			viewConfig: {
				forceFit: gridConfig.forceFit || false,
				emptyText: locale.string('text.no-matching-records.js')
			},

			sm: new Ext.grid.RowSelectionModel({ singleSelect:true }),

			listeners:
			{
				cellclick: function(grid, rowIndex, columnIndex) { this.edit(rowIndex, columnIndex); },
				scope: this
			}
			
		};
				
		var bbar = new Ext.PagingToolbar({
			displayInfo: true,
			pageSize: 25,
			store: store,
			prependButtons: true
			
		});
		
		if (gridConfig.bbar) {
			gridConfig.bbar = bbar;
		};

		if (gridConfig.stateful === undefined)
			stdConfig.stateful = stdConfig.stateId !== '';
		else
			stdConfig.stateful = gridConfig.stateful && stdConfig.stateId !== '';

		if (stdConfig.stateful)
		{
			stdConfig.listeners.beforestaterestore = this.applyGridState;
			Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
				expires: new Date(new Date().getTime()+(1000 * 60 * 60 * 24 * 7)), // 7 days from now
			}));
		}

		return Ext.apply(stdConfig, gridConfig);
	},

	applyGridState: function(component, state)
	{
		/*
			state is an object with two items:

			state:
			{
				columns:[
					{id: <config column index | column id>, width: <number>}
				],
				sort:
				{
					direction: "ASC" | "DESC"
					field: <name>
				}
			}
		*/

		var columns = [],
			colModel = component.getColumnModel();

		for (var i = 0; i < state.columns.length; ++i)
		{
			var columnState = state.columns[i],
				column = colModel.getColumnById(columnState.id);

			if (!column)
				continue;

			column.width = columnState.width;

			if (columnState.hidden)
				column.hidden = true;

			if (i == 0)
				column.menuDisabled = false;
			else
				column.menuDisabled = true;

			columns.push(column);
		}

		colModel.setConfig(columns);
		component.getStore().setDefaultSort(state.sort.field, state.sort.direction);

		// Suppress the built-in component restore
		return false;
	},

	edit: function(rowIndex, columnIndex)
	{
		if (this.editing || this.editConfig.mode === 'none')
			return;

		this.editing = true;
		this.record = this.grid.getSelectionModel().getSelected();
		this.mode = this.editConfig.mode || 'view';


		// Animate the window from the selected row
		var rowIndex = this.grid.getStore().indexOf(this.record),
			selectedRow = this.grid.getView().getRow(rowIndex),
			config =
			{
				id: this.editConfig.id,
				title: this.editDialogTitle(this.record),
				width: this.editConfig.width || 900,
				height: this.editConfig.height || 700,
				closable: false,
				resizable: true,
				modal: true,
				autoScroll: true,
				pdf: this.urls["pdf"],
				email: this.urls["email"],
				cls: 'ext-dialog',
				//animateTarget: selectedRow,
				url: this.editDialogContentUrl(this.record),
				list: this.grid,

				buttonAlign: 'center',
				bbar: new Ext.Toolbar({
					items: [
			
				]
				}),
				buttons: [ {
					text: locale.string('button.close.js'),
					handler: function()
					{
						this.editDialog.close();
						this.editing = false;
					},
					scope: this
				}
				]
			};
		if (this.mode === 'view')
		{
			if (this.urls["print"]) {
				URL = this.urls["print"] + "?id=" + this.record.id
				config.bbar.add(etraxx.onOpenWindow(locale.string('order.print-view.js'), URL,"icon-printer"));
			};
			
			if (this.urls["reorder"]) {
					URL = this.urls["reorder"] + "?id=" + this.record.id
					config.bbar.add('-')
					config.bbar.add(etraxx.onOpenLocation(locale.string('order.reorder.js'), URL,'icon-reorder'));
					
			};
			
			if (this.urls["order"]) {
					URL = this.urls["order"] + "?id=" + this.record.id
					config.bbar.add('-')
					config.bbar.add(etraxx.onOpenLocation(locale.string('order.order.js'), URL,'icon-reorder'));
					
			};
			if (this.urls["edit"]) {
					URL = this.urls["edit"] + "?id=" + this.record.id
					config.bbar.add(etraxx.onOpenLocation(locale.string('button.edit.js'), URL,'icon-edit'));
					
			};
			if (this.urls["destroy"]) {
					URL = this.urls["destroy"] + "?id=" + this.record.id
					config.bbar.add(etraxx.onConfirmLocation(locale.string('button.destroy.js'), URL,'icon-delete'));
					
			};
			
			
			
		}
		if (this.mode === 'edit')
		{
			config.buttons[0].text = locale.string('button.cancel.js');
			config.buttons[0].type = 'submit'
			config.buttons.unshift(
			{
				text: this.editConfig.saveButText || locale.string('button.save.js'),
				handler: function()
				{
					this.save();
				},
				scope: this,
				type: 'submit'
			});
		}

		this.editDialog = new Ext.ux.AjaxWindow(Ext.apply(config, this.editConfig));
		

	},

	onSaveSuccess: function()
	{
		this.editDialog.close();
		this.editing = false;
	}
});

Ext.onReady(etraxx.onReady);

