<#import "/spring.ftl" as spring>
/**
 * App.js
 *
 * @author Patrick
 */
App = {
	name: 'TBMS',
	version: '5.0',
	navMenu: [],
	localeMap_en: {},
	localeMap_zh: {},
	localeMap_ch: {},
	localeCode: '',
	userSettings: {
		"USER_materialItemGroup":"T",
		"USER_showMaterialItemCost": "F",
	},
	username: '${SecurityUtils.getUser().getUsername()?js_string}',
	fullname: '${SecurityUtils.getUser().getFullname()?js_string}',
	userAuths: [],
	msgPos: [ 0, 0, 0, 0, 0, 0, 0, 0 ],<#-- remember which msg position is currently being used -->
	fullMonthNames: ['January', 'February', 'March', 'April', 'May', 'June',
					'July', 'August', 'September', 'October', 'November', 'December'],
	monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
	debug: true,
	trace: false, <#-- show trace when log -->
	vp: null,
	autoRefreshInterval: 30000,
	intNumberFormat: '0,000',
	moneyNumberFormat: '0,000.00######',
	floatNumberFormat: '0,000.0000',
	unitCostFormat: '0,000.########',
	confirmedColor: '#80EA65',
	<#-- Ext.Date.format(date, format) -->
	dateFormat: 'd/m/Y',
	monthYearFormat: 'M Y',
	dateTimeFormat: 'Y-m-d H:i',
	timeFormat: 'H:i',
	dateTimeSubmitFormat: 'Y-m-d\\TH:i:s',
	dateTimeSecFormat: 'd/m/Y H:i:s',
	colDateTimeFormat: 'd/m/Y H:i',
	colDateFormat: 'd-m-Y',
	readOnlyStyle: 'background-color: #ddd;',
	linkStyle: 'color: blue; text-decoration:underline; cursor:pointer;',
	runner: new Ext.util.TaskRunner(),
	csrf: '${_csrf}',
	basePath: '<@spring.url "" />',
	panelAuths: new Map([
			["calendarContainer", ["CALENDAR_VIEW"]],
			["orderContainer", ["ORDER_MAINTAIN"]],
			["workshopContainer", ["WORKSHOP_MAINTAIN"]],
			["customerContainer", ["CUSTOMER_MAINTAIN"]],
			["report_PaymentContainer", ["PAYMENT_REPORT"]],
			["userBaseContainer", ["USER_MAINTAIN"]],
			["materialContainer", ["PRICE_LIST_VIEW","PRICE_LIST_MAINTAIN"]],
			["invoiceTemplateContainer", ["MATERIAL_MAIL_TEMPLATE"]],
		])
};

Ext.apply(App, {
	url: function(url) {
		return this.basePath + url;
	},

	log: function(o) {
		if (this.debug) {
			console.log(o);
			if (this.trace) console.trace();
		}
	},

	nl2br: function(v) {
		return Ext.isEmpty(v) ? v : v.replace(/\r?\n/g, '<br>');
	},

	confirm: function(msg, title, fn) {
		Ext.Msg.show({
			title: title || '<@spring.message "COMMON.pleaseConfirm"/>',
			msg: msg,
			width: 400,
			minHeight: 150,
			icon: Ext.Msg.QUESTION,
			buttons: Ext.Msg.YESNO,
			fn: fn || function(buttonId, text, opt) {
			}
		});
	},

	showInfo: function(msg, title, fn) {
		Ext.Msg.show({
			title: title || 'Information',
			msg: msg,
			width: 300,
			minHeight: 150,
			icon: Ext.Msg.INFO,
			buttons: Ext.Msg.OK,
			fn: fn || function(buttonId, text, opt) {
			}
		});
	},

	showWarning: function(msg, title) {
		Ext.Msg.show({
			title: title || 'Warning',
			msg: msg,
			width: 300,
			minHeight: 150,
			icon: Ext.Msg.WARNING,
			buttons: Ext.Msg.OK
		});
	},

	showError: function(msg, title) {
		Ext.Msg.show({
			title: title || 'Error',
			msg: msg,
			width: 300,
			minHeight: 150,
			icon: Ext.Msg.ERROR,
			buttons: Ext.Msg.OK
		});
	},

	showException: function(msg, details, title){
		Ext.Msg.show({
			title: title || 'Action Failure',
			msg: msg,
			width: 300,
			minHeight: 150,
			icon: Ext.Msg.ERROR,
			buttons: Ext.Msg.YESNO,
			buttonText: {yes: 'OK',no: 'Show Details'},
			fn: function(buttonId){
				if(buttonId=='no'){
					Ext.Msg.show({
						title: msg,
						msg: '<div style ="width: 550px; height:380px; border:1px solid black; overflow-x:scroll">' + details + '</div>',
						buttons: Ext.Msg.OK,
						fn: function(buttonId){
						}
					});
				}
			}
		});
	},

	showPrompt: function(msg, title, fn, multiLine){
		Ext.Msg.prompt(
			title,
			msg,
			fn || function(buttonId,value){},
			null,
			multiLine
		);
	},

	showMsg: function(msg, duration) {
		var me = this,
			pos = 0;

		<#-- find out which position is available -->
		for (var i = 0; i < me.msgPos.length; i++) {
			if (me.msgPos[i] == 0) {
				me.msgPos[i] = 1;
				pos = i;
				break;
			}
		}
		//console.log(pos);

		var bottom = pos * 65 + 30,
			el = Ext.getBody().createChild({ html: msg, style: 'display:none; position:fixed; bottom:' + bottom + 'px; right:30px; width:280px; height:60px; padding:20px; border-radius:10px; background-color:#64AA00; color:white; text-align:center; font-size:18px; z-index:99999;' });

		el.slideIn('b');
		setTimeout(function() { el.fadeOut({ remove: true }); me.msgPos[pos] = 0; }, duration || 2500);
	},

	initLoadMask: function() {
		if (!this.loadMask && Ext.isReady) this.loadMask = Ext.create('Ext.LoadMask', { target: App.vp });
	},

	checkAlphaCase: function(value) {
		var checkValue = value;
		<#if SettingsService.getString("autoUpperCase")?? && SettingsService.getString("autoUpperCase") == "1">
		if ((typeof checkValue) === 'string')
			checkValue = checkValue.toUpperCase();
		</#if>
		return checkValue;
	},

	setLoading: function(load) {
		this.initLoadMask();
		if (this.loadMask) {
			if (load)
				this.loadMask.show();
			else
				this.loadMask.hide();
		}
	},

	getInnerWidth: function() {
		return window.innerWidth || 1000;
	},
	getInnerHeight: function() {
		return window.innerHeight || 600;
	},

	location: function(url) {
		window.location.assign(url);
	},
	logout: function() {
		Ext.Ajax.request({
			url: App.url('/logout'),
			method: 'POST',
			callback: function(options, success, response) {
				location.reload();
				window.location.assign(this.basePath);
			}
		});
	},
	loadNavMenu: function(navMenu) {
		this.navMenu = navMenu || [];
	},
	getNavMenu: function() {
		return this.loopNavMenu(this.navMenu.items);
	},
	loopNavMenu: function(nav){
		var me = this;
		Ext.each(nav, function(n) {
			n.text = me.localeRes(n.text);
			n.title = me.localeRes(n.title);
			if(n.children){
				me.loopNavMenu(n.children);
			}
		});
		return nav;
	},
	loadLocale_EN: function(localeMap) {
		this.localeMap_en = localeMap || {};
	},
	loadLocale_ZH: function(localeMap) {
		this.localeMap_zh = localeMap || {};
	},
	loadLocale_CH: function(localeMap) {
		this.localeMap_ch = localeMap || {};
	},
	loadUserAuths: function(auths) {
		this.userAuths = auths || [];
	},
	setCustTooltip: function(name, phone, email){
		var str = name;
		str += phone?"<br/>"+phone:"";
		str += email?"<br/>"+email:"";
		return str;
	},
	setClickableCust: function(extId, custId, viewText, callback) {
		var me = this;
		if(!App.isGranted(this.getPanelAuths('customerContainer'))) return viewText;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('customerWindow', me.localeRes('Customer'), {
							params: { id: custId },
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		viewText = "<font color='#679b9b'><b>"+viewText+"</b></font>";

		return Ext.String.format('<b><a href="javascript:void(0);" id="{0}">{1}</a></b>', extId, viewText);
	},
	setClickableMaterial: function(extId, params, viewText, callback) {
		var me = this;
		if(!App.isGranted(this.getPanelAuths('materialContainer'))) return viewText;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('materialItemWindow', me.localeRes('Material'), {
							params: params,
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		viewText = "<font color='#679b9b'><b>"+viewText+"</b></font>";

		return Ext.String.format('<b><a href="javascript:void(0);" id="{0}">{1}</a></b>', extId, viewText);
	},
	setClickableCustOrder: function(extId, custId, viewText, callback) {
		var me = this;
		if(!App.isGranted(this.getPanelAuths('customerContainer'))) return viewText;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('customerOrderWindow', me.localeRes('Customer Order List'), {
							params: { id: custId },
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		viewText = "<font color='#679b9b'><b>"+viewText+"</b></font>";

		return Ext.String.format('<b><a href="javascript:void(0);" id="{0}">{1}</a></b>', extId, viewText);
	},
	setClickableOrder: function(extId, orderId, ignored, type, orderNo, callback) {
		var viewText = orderNo;
		if(ignored){ 
			//marked ignore
			viewText = "<font color='#CCD0D9'><b>"+orderNo+"</b></font>";
		}else if (type == OrderTypeCombo.TYPE_S){ 
			//S
			viewText = "<font color='#DB4C77'><b>" + orderNo + '</b></font>';
		}else{ 
			//SH
			viewText = "<font color='#10559A'><b>" + orderNo + '</b></font>';
		}
		var me = this;
		if(!App.isGranted(this.getPanelAuths('orderContainer'))) return viewText;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('orderWindow', App.localeRes('Order'), {
							params: { id: orderId },
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		return Ext.String.format('<b><a href="javascript:void(0);" id="{0}">{1}</a></b>', extId, viewText);
	},
	setClickableIcon: function(extId, id, icon,bank, callback) {
		var me = this;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('materialBandIconWindow', App.localeRes('Icon'), {
							params: { id: id },
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		return Ext.String.format('<a href="javascript:void(0);" id="{0}">{1}</a>&nbsp;&nbsp;&nbsp;{2}', extId, icon, bank);
	},


	setClickableWorkshop: function(extId, data, ignored, type, orderNo, callback) {
		var viewText = orderNo;
		if(ignored){ 
			//marked ignore
			viewText = "<font color='#CCD0D9'><b>"+orderNo+"</b></font>";
		}else if (type == OrderTypeCombo.TYPE_S){ 
			//S
			viewText = "<font color='#DB4C77'><b>" + orderNo + '</b></font>';
		}else{ 
			//SH
			viewText = "<font color='#10559A'><b>" + orderNo + '</b></font>';
		}
		var me = this;
		if(!App.isGranted(this.getPanelAuths('workshopContainer'))) return viewText;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						App.loadModuleWin('workshopWindow', App.localeRes('Workshop'), {
							params: { data: data },
							callbackOnClose: function() {
								if(callback) callback();
							}
						});
					}
				);
			}
		}, 200);

		return Ext.String.format('<b><a href="javascript:void(0);" id="{0}">{1}</a></b>', extId, viewText);
	},

	getNewButton: function(extId, text, onClick) {
		var me = this;
		setTimeout(function () {
			if (Ext.fly(extId)) {
				Ext.EventManager.addListener(
					extId, 'click',
					function () {
						onClick();
					}
				);
			}
		}, 200);

		return Ext.String.format('<button type="button" class="tbms-base-button tbms-button" id="{0}">{1}</button>', extId, text);
	},

	isGranted: function(auths) {
		if(!auths) return true;
		var me = this;
		
		if(me.userAuths.includes("SUPERUSER")){
			return true;
		}
		var isGranted = false;
		auths.forEach(function(value, index, array) {
			if(me.userAuths.includes(value)){
				isGranted =  true;
			}
		});
		return isGranted;
	},
	getLocaleStr: function(code){
		code = code?code:this.localeCode;
		if(code == 'zh_TW')
			return '繁';
		if(code == 'zh_CN')
			return '简';
		return 'Eng';
	},
	setLocale: function(code){
		this.localeCode = code;
	},
	initUserSetting: function(settings){
		if(settings!= null){
			for(var i=0; i < settings.length;i++){
				var item = settings[i];
				var itemName = item["name"];
				var itemValue = item["value"];
				this.userSettings[itemName] = itemValue;
			}
		}
	},
	setUserSetting: function(setting){
		this.userSettings[setting['name']]=setting['value'];
		Ext.Ajax.request({
			url: App.url('/user/setting/save'),
			params: { name: setting['name'], value: setting['value']},
			success: function(response, opts) {},
			failure: function(response, opts) {
				App.showError('Action Fail : ' + response.status);
			},
		});
	},
	getUserSetting: function(settingName){
		if(!this.userSettings) return "";
		if(!this.userSettings[settingName]) return "";
		return this.userSettings[settingName];
	},
	localeRes : function(key, ...args) {
		
		let str = this.localeMap_en[key] || key;
		if(this.localeCode == 'zh_TW')
			str = this.localeMap_zh[key] || key;
		else if(this.localeCode == 'zh_CN')
			str = this.localeMap_ch[key] || key;
		return args.reduce((_str, val) => _str.replace(/%s|%v|%d|%f|%d/, val), str);
	},
	delCoreFields: function(obj){
		// delete(obj.ownerId);
		// delete(obj.deleted);
		delete(obj.createdBy);
		delete(obj.modifiedBy);
		delete(obj.created);
		delete(obj.modified);
		delete(obj.password);
	},
	loadModule: function(xtype, title, params, hash) {
		if (xtype) {
			var alias = 'widget.' + xtype,
				className = Ext.ClassManager.getNameByAlias(alias),
				contentPanel = Ext.getCmp('mainContainer'),
				cmp;

			contentPanel.removeAll(true);

			if (className) {
				cmp = Ext.create(className, params);
				contentPanel.add(cmp);

				// contentPanel.setTitle('&nbsp;');
				// contentPanel.getHeader().hide();

				if (title) {
					//contentPanel.setTitle(title);
					//contentPanel.getHeader().show();
					document.title = title + ' - ' + App.name;
				} else if (cmp.title) {
					document.title = cmp.title + ' - ' + App.name;
				} else {
					document.title = App.name;
				}

				if (hash) location.hash = hash;

				return cmp;
			} else {
				contentPanel.setTitle('');
				this.showError('Module not found!');
			}
		}
	},
	
	loadModuleDash: function (xtype, title, params, hash) {
		if(!App.isGranted(App.getPanelAuths(xtype))){
			if(App.isGranted(["CALENDAR_VIEW"])){
				xtype = 'calendarContainer';
			}else if(App.isGranted(["WORKSHOP_MAINTAIN"])){
				xtype = 'workshopContainer';
			}else {
				xtype = 'report_OrderContainer';
			}
		}
		if (xtype) {
			var alias = 'widget.' + xtype,
				className = Ext.ClassManager.getNameByAlias(alias),
				Main = Ext.getCmp('main-view-detail-wrap'),
				contentPanel = Main.down('#contentPanel'),
				cmp;

			contentPanel.removeAll(true);
			Main.up("#mainView").down("#containerTitle").setHtml("<div class='container-title'>"+this.getTitle(xtype)+"</div>");


			if (className) {
				cmp = Ext.create(className, params);
				contentPanel.add(cmp);

				location.hash = xtype;

				return cmp;
			} else {
				this.showError('Module not found!');
			}
		}
	},

	loadModuleWin: function(xtype, title, params, hash) {
		if (xtype) {
			var alias = 'widget.' + xtype,
				className = Ext.ClassManager.getNameByAlias(alias),
				cmp;

			if (className) {
				cmp = Ext.create(className, params);
				cmp.show();

				if (title) {
					cmp.setTitle(title);
				}

<#--
				if (title) {
					cmp.setTitle(title);
					document.title = title + ' - ' + App.name;
				} else if (cmp.title) {
					document.title = cmp.title + ' - ' + App.name;
				} else {
					document.title = App.name;
				}
-->

				if (hash) location.hash = hash;

				return cmp;
			} else {
				this.showError('Module not found!');
			}
		}
	},

	<#--
		allowed url:
		/home#xxxPanel:{id}
		/home#xxxPanel:xxxId=1&xxx=true&xxx='asd'

		/home#xxxPanel:{id}:{title}
		/home#xxxPanel:xxxId=1&xxx=true&xxx='asd':{title}
	-->
	loadModuleByToken: function(token) {
		var delimiter = ':',
			parts = token.split(delimiter);

		if (parts.length > 1) {
			var title = '',
				params = {};

			if (parts.length > 2) title = decodeURI(parts[parts.length-1]).replace(/\&nbsp;/g, '');

			if (this.isInt(parts[1])){
				<#-- /home#xxxPanel:{id} -->
				if(parts[1] > 0)
					params.id = parts[1];
			}else{
				<#-- /home#xxxPanel:xxxId=1&xxx=true&xxx='asd' -->
				Ext.apply(params,Ext.JSON.decode('{"' + parts[1].replace(/\=/g, '":"').replace(/\&/g, '","') + '"}',true));
			}

			this.loadModule(parts[0], title, { params: params,
				askCloseEvent: (
					params.id ? function() {
						App.confirm('Close current tab?', 'Close current tab?', function(buttonId, text, option) {
							if (buttonId != 'yes') return false;
							window.close();
						});
					} : null
				)
			});
		} else {
			this.loadModule(parts[0]);
		}
	},
	addHistory: function(tokenStr){
		if(Ext.History.getToken() == tokenStr)
			this.loadModuleByToken(tokenStr);
		else
			Ext.History.add(tokenStr);
	},
	numberFormat: function(value, format){
		if(!value) value = 0;
		if(!format) format=App.moneyNumberFormat;
		return Ext.util.Format.numberRenderer(format)(value);
	},
	integerNumberFormat: function(value, format){
		if(!value) value = 0;
		if(!format) format=App.intNumberFormat;
		return Ext.util.Format.numberRenderer(format)(value);
	},
	isNumber: function(n){
		return Ext.isNumeric(n);
	},
	isInt: function(n){
		return App.isNumber(n) && n % 1 === 0;
	},
	isFloat: function(n){
		return App.isNumber(n) && n % 1 !== 0;
	},
	sec2HHMMSS: function(sec){
		var sec_num = parseInt(sec, 10);
		var hours   = Math.floor(sec_num / 3600);
		var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
		var seconds = sec_num - (hours * 3600) - (minutes * 60);
	
		if (hours   < 10) {hours   = "0"+hours;}
		if (minutes < 10) {minutes = "0"+minutes;}
		if (seconds < 10) {seconds = "0"+seconds;}
		return hours+':'+minutes+':'+seconds;
	},
	convertTimestampToTime: function(value){
		if(!value||value=='')return;
		return Ext.Date.format(new Date(value), "H:i");
	},
	convertTimestampToDate: function(value){
		if(!value||value=='')return;
		return Ext.Date.format(new Date(value), App.dateFormat);
	},
	convertTimestampToDateTime: function(value){
		if(!value||value=='')return;
		return Ext.Date.format(new Date(value), App.colDateTimeFormat);
	},
	getTitle: function(xtype){
		var me  = this;
		if(xtype == 'calendarContainer') return me.localeRes('Calendar');
		if(xtype == 'orderContainer') return me.localeRes('Order');
		if(xtype == 'workshopContainer') return me.localeRes('Workshop');
		if(xtype == 'customerContainer') return me.localeRes('Customer');
		if(xtype == 'settingContainer') return me.localeRes('Setting');
		if(xtype == 'report_PaymentContainer') return me.localeRes('Payment Report');
		if(xtype == 'report_OrderContainer') return me.localeRes('Orders Report');
		if(xtype == 'report_OutstandingContainer') return me.localeRes('Outstanding Report');
		if(xtype == 'report_CustomerContainer') return me.localeRes('Customer Report');
		if(xtype == 'userBaseContainer') return me.localeRes('User Setting');
		if(xtype == 'materialContainer') return me.localeRes('Price List');
		if(xtype == 'invoiceTemplateContainer') return me.localeRes('Mail Settings');
		if(xtype == 'systemGroupContainer') return me.localeRes('System Settings');
		return xtype;
	},
	getPanelAuths: function(xtype){
		return this.panelAuths.get(xtype) || '';
	},
	runTask: function(func, interval){
		if(func == null) return null;
		return App.runner.start({
			run: func,
			interval: interval
		});
	},
	stopTask: function(task, andRemove){
		App.runner.stop(task, andRemove);
	},
	stopAllTask: function(andRemove){
		App.runner.stopAll(andRemove);
	},
	codePadding: function(num, width, sym){
		sym = sym || '0';
		num = num.toString();
		if(num.length >= width) return num;
		return new Array((width - num.length)+1).join(sym) + num;
	},
	setStatusStyle: function(value){
		<#-- 2/10/2018
		common			: pending, confirmed, cancelled, completed, closed
		e-order			: draft
		jobNo			: released
		DN				: hold, passed
		quotation		: awarded
		contract		: inactive, active, expired
		-->
		if (!value) return '';
		if (value == 'draft') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">Draft</span>';
		if (value == 'New') return '<span style="font-size:11px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">New</span>';
		if (value == 'confirmed') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #00cc66; text-shadow: 1px 1px 0 #444;">Confirmed</span>';
		if (value == 'Completed') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #cc00ff; text-shadow: 1px 1px 0 #444;">Completed</span>';
		if (value == 'closed') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #444; text-shadow: 1px 1px 0 #444;">Closed</span>';
		if (value == 'Cancelled') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #444; text-shadow: 1px 1px 0 #444;">Cancelled</span>';
		if (value == 'released') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">Released</span>';

		if (value == 'hold') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #00cc66; text-shadow: 1px 1px 0 #444;">Hold</span>';
		if (value == 'passed') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">Passed</span>';

		if (value == 'awarded') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #0978E1; text-shadow: 1px 1px 0 #444;">Awarded</span>';

		if (value == 'active') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #00cc66; text-shadow: 1px 1px 0 #444;">Active</span>';
		if (value == 'expired') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">Expired</span>';
		
		if (value == 'paid') return '<span style="font-size:13px; font-family: tahoma; padding: 2px 5px; color: white; background-color: #777; text-shadow: 1px 1px 0 #444;">Paid</span>';

		return '<span style="font-size:13px; font-family: tahoma; padding: 0px 3px; color: grey; border-style: groove; border-width: 2px;">' + Ext.util.Format.capitalize(value) + '</span>';

	},
	setPriorityStyle: function(value){
		if (value == 'Not Urgent') return '<span style="font-size:13px; padding: 0px 5px; color: grey; border-style: groove; border-width: 2px;">Not Urgent</span>';
		if (value == 'Urgent') return '<span style="font-size:14px; padding: 2px 5px; color: white; background-color: #FF8000; text-shadow: 1px 1px 0 #444;">Urgent</span>';
		return '<span style="font-size:14px; padding: 0px 3px; color: grey; border-style: groove; border-width: 2px;">' + Ext.util.Format.capitalize(value) + '</span>';
	},

	setPosNegStyle: function(value){
		if (value >= 0) return '<p style="font-size: 13px; color:#2db87c; border-width: 0px;margin-block-start:0; margin-block-end:0; margin-inline-start:0; margin-inline-end:0; padding-block-start:0; padding-block-end:0; padding-inline-start:0; padding-inline-end:0;"><b>'+ Ext.util.Format.number(value, "0,000.##") + '</b></p>';
		if (value < 0 ) return '<p style="font-size: 13px; color:#fa0b0c; border-width: 0px;margin-block-start:0;margin-block-end:0; margin-inline-start:0; margin-inline-end:0; padding-block-start:0; padding-block-end:0; padding-inline-start:0; padding-inline-end:0;"><b>' + Ext.util.Format.number(value, "0,000.##") + '</b></p>';
},

	newDate: function (day, month, year, hr, min, sec) {
		var d = new Date();
		if (day) d.setDate(d.getDate() + day);
		if (month) d.setMonth(d.getMonth() + month);
		if (year) d.setFullYear(d.getFullYear() + year);
		if (hr) d.setHours(d.getHours() + hr);
		if (min) d.setMinutes(d.getMinutes() + min);
		if (sec) d.setSeconds(d.getSeconds() + sec);
		return d;
	},
	printImage: function(source){
        if(!source || source=="" || source.length==0 ) return;
        var str = "<html>"
        +"<head>"
            +"<style>"
                +" @media all {.page-break { display: none; }} "
                +" @media print {.page-break { display: block; page-break-before: always; }} "
            +"</style>"
            +"<script>"
                +"function step1(){setTimeout('step2()', 10);}" 
                +"function step2(){window.print();window.close()}" 
            +"</script>"
        +"</head>"
        +"<body onload='step1()'>" +this.setImageTab(source) + "</body>"
        +"</html>";
        var Pagelink = "about:blank";
        var pwa = window.open(Pagelink, "_new");
        pwa.document.open();
        pwa.document.write(str);
        pwa.document.close();
    },
    setImageTab:function(source){
        var sourceStr = "";
        for(var i = 0; i<source.length; i++){
            sourceStr = sourceStr+"<div class='page-break'><img src='" + source[i] + "' /></div>"
        }
        return sourceStr;
    },

});


<#-- Default header for CSRF -->
//Ext.Ajax.setDefaultHeaders({ 'X-CSRF-TOKEN': '${_csrf}' });
Ext.util.Cookies.set('X-CSRF-TOKEN', '${_csrf}');
Ext.Ajax.onBefore('beforerequest', function(conn, options){
	options.headers = options.headers || {};
	Ext.apply(options.headers,{
		'X-CSRF-TOKEN': Ext.util.Cookies.get('X-CSRF-TOKEN')
	});
});

Ext.Ajax.onAfter('requestexception',function(conn, response, options){
	if (options.retry--) {
		Ext.defer(function() {
			Ext.Ajax.request(options)
		}, 300 + Math.random() * 500 );
	} else {
		App.log("requestexception: " + response.status);
		if(response.responseText == 'DataIntegrityViolation'){
			App.showError('Data Integrity Violation');
			return;
		}
		
		if(response.status == 403 && response.request.url != '<@spring.url "/logout" />'){
			alert('<@spring.message "SESSION.timeout.message" />');
			location.reload();
			return;
		}
		
		<#-- Exception handling -->
		if(response.status == 500){
			App.log("requestexception: 500");
			try{
				var result = Ext.decode(response.responseText);
				if(result.msg){
					App.showException(result.msg,response.responseText);
				}else{
					App.showException("Request Exception: 500",response.responseText);
				}
			}catch(e){
				App.showException("Request Exception: 500",response.responseText);
			}
		}
	}
});

Ext.History.on('change', function(token) {
    if (token) {
       App.loadModuleDash(token, App.getTitle(token));
    }
});


<#--
Combo Renderer for Grid

@param combo
	required, the combo to search for display value
@param recordDisplayField
	required, the display field in grid store record object to get display value from (useful when first rendering the grid since the combo store is not loaded yet)
@param comboValueField
	optional (defaults to combo.valueField), the value field used in combo.findRecord(valueField)
@param comboDisplayField
	optional (defaults to combo.displayField), the display field used to get the display value from the record object resulted from combo.findRecord(valueField)
-->
Ext.util.Format.comboRenderer = function(combo, recordDisplayField, comboValueField, comboDisplayField) {
	return function(value, metaData, record, row, col, store, grid) {
		var r = combo.findRecord(comboValueField || combo.valueField, value);
		var v = r ? r.get(comboDisplayField || combo.displayField) : record.get(recordDisplayField) || combo.valueNotFoundText || value;
		if (metaData) metaData.tdAttr = 'data-qtip="' + v + '"';
		return v;
	};
};
