Ext.define("Ext.ux.hsvwheel.Field", {

	extend: "Ext.form.field.Picker",

	alias: ["widget.hsvwheelfield"],

	/**
	 * @cfg {String} [triggerCls="x-form-date-trigger"]
	 * An additional CSS class used to style the trigger button. The trigger will always get the class "x-form-trigger"
	 * and triggerCls will be **appended** if specified (default class displays a calendar icon).
	 */
	triggers: {
		cls: "x-ux-hsvwheel-trigger",
		handler: "onTriggerClick",
		scope: "this"
	},

	enableKeyEvents: true,
	enforceMaxLength: true,
	maxLength: 6,
	cls: "x-ux-hsvwheel-field",
	maskRe: /[a-f0-9]/i,
	regex: /^([0-9a-f]{3}){1,2}$/i,
	regexText: "Not a valid hex color must be a character (A-F) or a number (0-9) - as well have a length of 3 or 6",
	validateOnChange: true,

	onFocusLeave: Ext.emptyFn,

	squared: true,

	__silencePicker: false,

	_preview: null,

	initComponent: function () {

		var i_cmp = this;

		i_cmp.callParent(arguments);

		i_cmp.on({
			"afterrender": {
				fn: i_cmp.onAfterRender
			}
		});

		return i_cmp;
	},

	initValue: function () {

		var i_cmp = this;
		i_cmp.value = i_cmp.value || "";
		var value = i_cmp.value;

		i_cmp.originalValue = value;

		i_cmp.setValue(value);

		return i_cmp;
	},

	addControls: function () {

		var i_cmp = this;

		i_cmp.on({
			"keyup": {
				fn: function () {
					var s_hex = i_cmp.inputEl.getValue();
					i_cmp.setValue(s_hex);
				}
			}
		});
	},

	onAfterRender: function () {

		var i_cmp = this;

		i_cmp.createPreview();

		i_cmp.addControls();

		return i_cmp;
	},
	onChange: function (s_hex) {

		var i_cmp = this;

		if (i_cmp.rendered) {
			var i_picker = i_cmp.getPicker();
			var b_silencePicker = i_cmp.__silencePicker;

			if (!b_silencePicker && i_picker) {
				i_cmp.getPicker().select(s_hex);
			}

			i_cmp.updatePreview(s_hex);
			i_cmp.validate();
		}

		return i_cmp;
	},
	onExpand: function () {

		var i_cmp = this;
		var i_picker = i_cmp.getPicker();
		var s_value = this.getValue();

		i_picker.select(s_value);
	},
	onCollapse: function () {

		var i_cmp = this;

		i_cmp.focus(false, 60);
	},

	createPicker: function () {

		var i_cmp = this;
		var i_picker;

		i_picker = Ext.widget("hsvwheelpicker", {
			pickerField: i_cmp,
			ownerCt: i_cmp.ownerCt,
			renderTo: document.body,
			floating: true,
			hidden: true,
			focusOnShow: true,
			listeners: {
				update: function (i_picker, s_hex) {
					i_cmp.__silencePicker = true;

					// TODO - get a sweet regex here - should be easy
					s_hex = s_hex.replace("#", "");
					i_cmp.setValue(s_hex);
					i_cmp.__silencePicker = false;
				}
			},
			keyNavConfig: {
				esc: function() {
					i_cmp.collapse();
				}
			}
		});

		return i_picker;
	},

	createPreview: function () {

		var i_cmp = this;
		var s_hex = i_cmp.getValue();
		var i_inputEl = i_cmp.inputEl;
		var i_preview;

		Ext.DomHelper.insertBefore(i_inputEl,
			"<div style=\"" +
				"position: absolute;" +
				"top: 40%;" +
				"left: 5px;" +
				"width: 11px;" +
				"height: 11px;" +
				"border: 1px solid #000000;" +
				"background-color: transparent;\"" +
			"></div>"
		);
		i_cmp._preview = i_inputEl.prev();

		i_cmp.updatePreview(s_hex);

		return i_cmp;
	},
	getPreview: function () {

		return this._preview;
	},
	updatePreview: function (s_hex) {

		var i_cmp = this;
		var i_preview = i_cmp.getPreview();
		var s_value = s_hex.replace("#", "");
		var b_valid = i_cmp.validateValue(s_value);

		if (!i_preview) {
			return i_cmp;
		}

		if (b_valid) {

			i_preview.removeCls("error");
			i_preview.setStyle("background-color", s_hex);
		}
		else {
			i_preview.addCls("error");
		}

		return i_cmp;
	},

	update: function (s_hex) {

		var i_cmp = this;

		i_cmp.setValue(s_hex);

		return i_cmp;
	},

	getValue: function () {

		var i_cmp = this;
		var s_value = i_cmp.value;
		if (s_value) {
			s_value = "#" + s_value;
		}
		return s_value;
	},

	setValue: function (s_hex) {

		var i_cmp = this;
		if (s_hex && s_hex.indexOf("#") == 0) {
			s_hex = s_hex.slice(1);
		}

		if (!s_hex) {
			s_hex = "";
		}

		i_cmp.callParent([s_hex]);
		if (i_cmp.originalValue.indexOf("#") == -1) {
			i_cmp.resetOriginalValue();
		}

		return i_cmp;
	},

	/**
	 * @param {Object} [value] The value to get errors for (defaults to the current field value)
	 * @return {String[]} All validation errors for this field
	 */
	getErrors: function (value) {

		var i_cmp = this;
		var a_errors = i_cmp.callParent(arguments);

		var s_value = i_cmp.value;

		return a_errors;
	}
});
