Ext.define("IceCap.util.Handler", {

	singleton: true,

	config: {
		scaling: {
			colSize: 9.7,
			textSize: 16,
			defaultWidth: 18,
			defaultHeight: 24,
			lineHeight: 28
		},
		sessions: [],
		fixed: true,
		scaleSize: 14,
		marginValue: 4,
		scale: 1,
		serviceUrl: "/icecap/icecap.aspx",
		provider: null
	},

	FFW: {
		// FFW identification flag (0 - 1)
		// Bypass (2)
		// Dup or Field Mark Enable (3)
		//  Modified Data Tag (MDT) (4)
		// Field Shift/Edit Specification (5 - 7)
		// Auto Enter (8)
		// Field Exit Required (FER) (9)
		// Monocase (10)
		// Reserved (11)
		// Mandatory Enter (ME) (12)
		// Right Adjust/Mandatory Fill (MF) (13-15)
		IDENT_FLAG: (1 << 0),
		BYPASS: (1 << 1),
		DUP_OR_MARK: (1 << 2),
		MOD_DATA: (1 << 3),
		APLHA_SHIFT: (1 << 4),
		ALPHA_ONLY: (1 << 5),
		NUMERIC_SHIFT: (1 << 6),
		NUMERIC_ONLY: (1 << 7),
		KATAKANA_SHIFT: (1 << 8),
		DIGITS_ONLY: (1 << 9),
		IO_FEATURE: (1 << 10),
		SIGNED_NUMERIC: (1 << 11),
		AUTO_ENTER: (1 << 12),
		EXIT_REQ: (1 << 13),
		MONOCASE: (1 << 14),
		MAND_ENTER: (1 << 15),
		RA_NONE: (1 << 16),
		RA_ZEROFILL: (1 << 17),
		RA_BLANKFILL: (1 << 18),
		RA_FILL: (1 << 19),
		RA_RESERVED: (1 << 20),
		RA_MANDATORY: (1 << 21),
		RA_READONLY: (1 << 22)
	},

	typeMode: {
		OVERWRITE: 1,
		INSERT: 2
	},

	requires: [
		"IceCap.state.session.Provider",
		"IceCap.state.local.Provider",
		"IceCap.util.Watchdog"
	],

	constructor: function(o_config) {

		var i_self = this;
		i_self.initConfig(o_config);

		var i_provider = Ext.widget("icecap-state-local-provider", {});

		i_self.setProvider(i_provider);

		return this;
	},

	getPath: function(o_config) {

		var s_base = IceCap.util.Handler.getServiceUrl();
		var s_session = o_config.session;
		var s_activeTerminals = IceCap.util.Handler.getActiveTerminals();

		if (s_activeTerminals) {
			Ext.apply(o_config, {
				activeTerminals: s_activeTerminals
			});
		}

		return s_session + "" + s_base + "?" + Ext.urlEncode(o_config);
	},

	getX: function(n_col) {
		return Math.ceil(n_col * IceCap.util.Handler.getColSize());
	},

	getY: function(n_lin) {
		return Math.ceil(n_lin * IceCap.util.Handler.getLineHeight());
	},

	toColAndLine: function(o_values) {

		var n_x = o_values.x - IceCap.util.Handler.getColSize();
		var n_y = o_values.y;

		var n_col = Math.ceil(n_x / IceCap.util.Handler.getColSize()) || 1;
		var n_lin = Math.floor(n_y / IceCap.util.Handler.getLineHeight()) || 1;

		var o_position = Ext.apply({}, {
			col: n_col,
			lin: n_lin
		});

		return o_position;
	},

	getColSize: function() {
		var o_scale = IceCap.util.Handler.getScalingObject();
		return o_scale.colSize * IceCap.util.Handler.getScale();
	},

	getLineHeight: function() {
		var o_scale = IceCap.util.Handler.getScalingObject();
		return o_scale.lineHeight * IceCap.util.Handler.getScale();
	},

	getMargin: function() {
		return IceCap.util.Handler.getMarginValue() * IceCap.util.Handler.getScale();
	},

	getTextSize: function() {
		var o_scale = IceCap.util.Handler.getScalingObject();
		return o_scale.textSize * IceCap.util.Handler.getScale();
	},

	getDefaultWidth: function() {
		var o_scale = IceCap.util.Handler.getScalingObject();
		return o_scale.defaultWidth * IceCap.util.Handler.getScale();
	},

	getDefaultHeight: function() {
		var o_scale = IceCap.util.Handler.getScalingObject();
		return o_scale.defaultHeight * IceCap.util.Handler.getScale();
	},

	getData: function(o_config, o_data, f_callback) {

		f_callback = f_callback || Ext.emptyFn;
		o_data = o_data || {};

		Ext.Ajax.request({
			url: IceCap.util.Handler.getPath(o_config),
			method: "POST",
			params: o_data,
			success: function(i_response, i_request) {

				var o_data = Ext.apply({}, {
					input: [],
					output: []
				});
				if (!Ext.String.startsWith(!i_response.responseText.toLowerCase(), "<html")) {

					Ext.USE_NATIVE_JSON = false; // DO THIS TO ALLOW THE PARSE OF FUNCTIONS

					o_data = Ext.decode(i_response.responseText, true) || Ext.apply({}, {
						input: [],
						output: []
					});

					//Ext.USE_NATIVE_JSON = true;
				}
				f_callback(o_data);
			},
			failure: function() {
				f_callback({
					input: [],
					output: []
				});
			}
		});
	},

	getNewSession: function(f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var s_activeTerminals = IceCap.util.Handler.getActiveTerminals();

		Ext.Ajax.request({
			url: IceCap.util.Handler.getServiceUrl() + "?activeTerminals=" + s_activeTerminals,
			method: "POST",
			success: function(i_response, i_request) {

				var o_data = Ext.decode(i_response.responseText, true) || Ext.apply({}, {
					success: false,
					session: ""
				});

				IceCap.util.Handler.addSession(o_data.session);

				f_callback(o_data);
			},
			failure: function(o_err) {

				var o_data = Ext.apply({}, {
					success: false,
					session: ""
				});
				f_callback(o_data);
			}
		});
	},

	useScale: function(n_scale) {

		var o_scale = IceCap.util.Scale.getFixed()[n_scale];

		if (o_scale) {
			IceCap.util.Handler.setScaling(o_scale);
		}
	},

	addSession: function(s_session) {

		var i_provider = IceCap.util.Handler.getProvider();

		var a_terminals = Ext.Array.from(i_provider.get("activeterminals"));

		var s_terminal = s_session.substring(s_session.length - 2);
		var n_terminal = parseFloat(s_terminal);

		if (isNaN(n_terminal)) {
			n_terminal = 0;
		}

		if (n_terminal && Ext.Array.indexOf(a_terminals, n_terminal) === -1) {
			a_terminals.push(n_terminal);
		}

		i_provider.set("activeterminals", a_terminals);

		var a_sessions = IceCap.util.Handler.getSessions() || [];

		 Ext.Array.push(a_sessions, s_session);

		IceCap.util.Handler.setSessions(a_sessions);
	},

	getActiveTerminals: function() {

		var i_provider = IceCap.util.Handler.getProvider();

		var a_terminals = Ext.Array.from(i_provider.get("activeterminals"));

		if (a_terminals.length === 0) {
			a_terminals.push(0);
		}

		return a_terminals.join(",");
	},

	removeSession: function(s_session) {

		var i_provider = IceCap.util.Handler.getProvider();

		var a_terminals = Ext.Array.from(i_provider.get("activeterminals"));

		var s_terminal = s_session.substring(s_session.length - 2);
		var n_terminal = parseFloat(s_terminal);

		if (isNaN(n_terminal)) {
			n_terminal = 0;
		}

		if (n_terminal) {
			Ext.Array.remove(a_terminals, n_terminal);
		}

		i_provider.set("activeterminals", a_terminals);

		var a_sessions = IceCap.util.Handler.getSessions() || [];

		Ext.Array.remove(a_sessions, s_session);

		IceCap.util.Handler.setSessions(a_sessions);
	},

	isSessionAlive: function(s_session, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		IceCap.util.Handler.addSession(s_session);

		Ext.Ajax.request({
			url: IceCap.util.Handler.getServiceUrl() + "?activeTerminals=" + IceCap.util.Handler.getActiveTerminals(),
			method: "POST",
			params: {
				isSessionAlive: s_session
			},
			success: function(i_response, i_request) {

				var o_result = Ext.decode(i_response.responseText, true) || Ext.apply({}, {
					success: false,
					message: ""
				});

				f_callback(o_result.success);
			},
			failure: function(o_err) {

				IceCap.util.Handler.removeSession(s_session);

				var o_result = Ext.apply({}, {
					success: false,
					session: ""
				});

				f_callback(o_result.success);
			}
		});
	},

	getScalingObject: function() {

		var b_fixed = IceCap.util.Handler.getFixed();
		var o_return = IceCap.util.Handler.getScaling();
		var n_scale = IceCap.util.Handler.getScaleSize();
		if (!b_fixed) {
			var o_free = IceCap.util.Scale.getFree()[n_scale];
			if (o_free) {
				o_return = o_free;
			}
		}

		return o_return;
	},

	createWindow: function(o_config) {

		var o_icecap = {
			func: o_config.func,
			initFunc: o_config.initFunc,
			responseCallBack: o_config.responseCallBack,
			requestCallBack: o_config.requestCallBack,
			theme: o_config.theme
		};

		var i_icecap = Ext.create("IceCap.view.Main", o_icecap);

		var i_window = Ext.widget("window", Ext.apply(o_config, {
			onEsc: Ext.emptyFn,
			items: [
				i_icecap
			]
		}));

		i_icecap.on({
			destroy: {
				fn: function () {
					if (!i_window.isDestroyed && !i_window.destroying) {
						i_window.close();
					}
				}
			}
		});

		return i_window;
	},

	createIndicators: function(s_hex16) {

		var i_self = this;

		// EXAMPLE
		// WE READ FROM LEFT TO RIGHT BITWISE
		// 0100 0011 0000 0110

		// 1 IN 16 BITS
		// RESULT 0000 0000 0000 0001

		// (1 << 15) SHIFT LEFT 15 BIT
		// RESULT 1000 0000 0000 0000

		var n_hex32 = 0;

		var n_hex16 = parseInt(s_hex16);

		if (!(n_hex16 & (1 << 15)) && (n_hex16 & (1 << 14))) {
			n_hex32 |= IceCap.util.Handler.FFW.IDENT_FLAG;
		}

		if (n_hex16 & (1 << 13) || (n_hex16 & (1 << 10 | 1 << 9 | 1 << 8) == (1 << 10 | 1 << 9))) {
			n_hex32 |= IceCap.util.Handler.FFW.BYPASS;
		}
		if (n_hex16 & (1 << 12)) {
			n_hex32 |= IceCap.util.Handler.FFW.DUP_OR_MARK;
		}
		if (n_hex16 & (1 << 11)) {
			n_hex32 |= IceCap.util.Handler.FFW.MOD_DATA;
		}

		n_hex32 |= i_self.ffw_spec(n_hex16);

		if (n_hex16 & (1 << 7)) {
			n_hex32 |= IceCap.util.Handler.FFW.AUTO_ENTER;
		}
		if (n_hex16 & (1 << 6)) {
			n_hex32 |= IceCap.util.Handler.FFW.EXIT_REQ;
		}
		if (n_hex16 & (1 << 5)) {
			n_hex32 |= IceCap.util.Handler.FFW.MONOCASE;
		}
		if (n_hex16 & (1 << 3)) {
			// n_hex32 |= IceCap.util.Handler.FFW.MAND_ENTER;
		}

		n_hex32 |= i_self.ffw_ra(n_hex16);

		return n_hex32;
	},

	ffw_spec: function(n_flag) {

		if (n_flag & (1 << 10) && n_flag & (1 << 9) && n_flag & (1 << 8)) {
			return IceCap.util.Handler.FFW.SIGNED_NUMERIC;
		}
		if (n_flag & (1 << 10) && n_flag & (1 << 9) && !(n_flag & (1 << 8))) {
			return IceCap.util.Handler.FFW.IO_FEATURE;
		}
		if (n_flag & (1 << 10) && !(n_flag & (1 << 9)) && n_flag & (1 << 8)) {
			return IceCap.util.Handler.FFW.DIGITS_ONLY;
		}
		if (n_flag & (1 << 10) && !(n_flag & (1 << 9)) && !(n_flag & (1 << 8))) {
			return IceCap.util.Handler.FFW.KATAKANA_SHIFT;
		}
		if (!(n_flag & (1 << 10)) && n_flag & (1 << 9) && n_flag & (1 << 8)) {
			return IceCap.util.Handler.FFW.NUMERIC_ONLY;
		}
		if (!(n_flag & (1 << 10)) && n_flag & (1 << 9) && !(n_flag & (1 << 8))) {
			return IceCap.util.Handler.FFW.NUMERIC_SHIFT;
		}
		if (!(n_flag & (1 << 10)) && !(n_flag & (1 << 9)) && n_flag & (1 << 8)) {
			return IceCap.util.Handler.FFW.ALPHA_ONLY;
		}

		return IceCap.util.Handler.FFW.APLHA_SHIFT;
	},

	ffw_ra: function(n_flag) {

		if (!(n_flag & (1 << 2)) && !(n_flag & (1 << 1)) && !(n_flag & (1 << 0))) {
			return IceCap.util.Handler.FFW.RA_NONE;
		}
		if ((n_flag & (1 << 2)) && !(n_flag & (1 << 1)) && (n_flag & (1 << 0))) {
			return IceCap.util.Handler.FFW.RA_ZEROFILL;
		}
		if ((n_flag & (1 << 2)) && (n_flag & (1 << 2)) && !(n_flag & (1 << 0))) {
			return IceCap.util.Handler.FFW.RA_BLANKFILL;
		}
		if ((n_flag & (1 << 2)) && (n_flag & (1 << 2)) && (n_flag & (1 << 0))) {
			return IceCap.util.Handler.FFW.RA_MANDATORY;
		}

		return IceCap.util.Handler.FFW.RA_RESERVED;
	}
});
