/*
    Copyright (c) 2006-2007, ePages GmbH
    All Rights Reserved.

    epages.cartridges.de_epages.product.widget.VariationAttributeList

*/
dojo.provide("epages.cartridges.de_epages.product.widget.VariationAttributeList");
dojo.require("epages.uimessagehandler");
dojo.require("epages.widget.LocalizedWidget");
dojo.require("epages.widget.FormElement");
dojo.require("epages.widget.Tooltip");
dojo.require("epages.event");
dojo.require("epages.validate.string");

dojo.declare("epages.cartridges.de_epages.product.widget.VariationAttributeList", [epages.widget.LocalizedWidget], {
	/**
	 * public properties
	 */
	allowDuplicates: "false",
	attributeAlias: "",
	autoEmptyRow: "true",
	emptyInputNamePrefix: "EmptyValue",
	isLocalized: "true",
	isNew: "false",
	isUsed: "false",
	newInputNamePrefix: "VariationAttributeValues",
	maxAttributeValues: 10,
	nextButtonId: '',

	/**
	 * private properties
	 */
	_attributeCounter: '', // String - remember counter to set input names
	_oldValues: undefined, // String[] - array of old values
	_widgetsOfClass: [], // dijit._Widget[] - list of widgets (used by all widgets of this class)
	_existingAttributes: [], // String[] - list of all existing attribute alias of product type

	/**
	 * widget properties
	 */
	templatePath: dojo.moduleUrl('epages.cartridges.de_epages.product.widget', "templates/VariationAttributeList.html"),
	translationName: dojo.moduleUrl('epages.cartridges.de_epages.product.widget', 'templates/translation'),
	imagePath: epages.themeUrl('images'),
	widgetsInTemplate: true,

	postMixInProperties: function () {
		this.inherited("postMixInProperties", arguments);
		this.autoEmptyRow = epages.string.toBoolean(this.autoEmptyRow);
		this.allowDuplicates = epages.string.toBoolean(this.allowDuplicates);
		this.isLocalized = epages.string.toBoolean(this.isLocalized);
		this.isNew = epages.string.toBoolean(this.isNew);
		this.isUsed = epages.string.toBoolean(this.isUsed);
		this._oldValues = [];
		this._attributeCounter = this._widgetsOfClass.length;
		this._widgetsOfClass.push(this);
	},

	setAttributeCounter: function (counter) {
		this.typePackageNode.name = "TypePackage" + counter;
		this.attributeAliasNode.name = "VariationAttributeAlias" + counter;
		this.attributeAliasHiddenNode.name = "VariationAttributeAlias" + counter;
		this.isUsedValueNode.name = "UseAttribute" + counter;
		this.headlineNode.innerHTML = "" + (Number(counter) + 1);
		this._attributeCounter = counter;
		this.reorgInputs();
	},

	startup: function () {
		this.inherited("startup", arguments);
		if (this.autoEmptyRow) {
			this.addNewRow();
		}
		this.setAttributeCounter(this._attributeCounter);
		// set initial values for localized
		this.localizableNode.attr('checked', this.isLocalized);
		this._onLocalizedClick();
		if (this.isNew) {
			this.attributeAliasHiddenNode.parentNode.removeChild(this.attributeAliasHiddenNode);

			// activate attribute alias
			this.connect(this.attributeAliasNode, 'onchange', '_onChangeAttributeAlias');
			this.connect(this.attributeAliasNode, 'onkeyup', '_onChangeAttributeAlias');
			this.connect(this.attributeAliasNode, 'onclick', '_onChangeAttributeAlias');
			this.attributeAliasNode.disabled = false;
			dojo.removeClass(this.attributeAliasNode, 'Disabled');

			// activate localized checkbox
			this.connect(this.localizableNode.elementNode, 'onclick', '_onLocalizedClick');
			this.localizableNode.attr('disabled', false);

			// activate delete attribute link
			this.connect(this.deleteAttributeNode, 'onclick', '_onClickDeleteAttribute');
			dojo.removeClass(this.deleteAttributeNode, 'HideElement');
		}
		// active use variation attribute checkout
		if (this.isUsed || this.isNew) {
			dojo.addClass(this.isUsedBlockNode, 'HideElement');
			this.isUsedFormNode.attr('disabled', true);
		} else {
			this.connect(this.isUsedFormNode.elementNode, 'onclick', '_onIsUsedClick');
		}
	},

	rows: function () {
		return dojo.filter(this.tableBodyNode.childNodes, function (el) {
			return el.nodeName == 'TR';
		});
	},

	_setAlternateClass: function () {
		var alternate = true;
		dojo.forEach(this.rows(), function (el) {
			alternate = !alternate;
			if (alternate) {
				dojo.addClass(el, 'alternate');
			} else {
				dojo.removeClass(el, 'alternate');
			}
		});
	},

	getInput: function (row) {
		var inputs = dojo.query('.jsInput', row);
		return inputs.length > 0 ? inputs[0] : undefined;
	},

	getInputs: function () {
		var inputs = [];
		dojo.forEach(this.rows(), function (row) {
			var r = dojo.query('.jsInput', row);
			if (r.length > 0) {
				inputs.push(r[0]);
			}
		});
		return inputs;
	},

	getAnchor: function (row) {
		return dojo.query('.jsAnchor', row)[0];
	},

	addValue: function ( /*String*/ alias) {
		// get existing rows and template
		var rows = this.rows();
		var template = rows[rows.length - 2];
		// create new row
		var newRow = template.cloneNode(true);
		var cells = dojo.filter(newRow.childNodes, function (el) {
			return el.nodeName == 'TD';
		});
		cells[0].innerHTML = alias;
		dojo.removeClass(newRow, 'HideElement');
		// insert before template and new elements
		this.tableBodyNode.insertBefore(newRow, rows[this._oldValues.length]);
		// add to internal values
		this._oldValues.push(alias);
		this._setAlternateClass();
	},

	addNewRow: function () {
		if (this.getInputs().length + this._oldValues.length > this.maxAttributeValues) {
			return;
		}

		// get existing rows and template
		var rows = this.rows();
		var template = rows[rows.length - 1];
		// create new row
		var row = template.cloneNode(true);
		var input = this.getInput(row);
		input.name = this.emptyInputNamePrefix;
		var anchor = this.getAnchor(row);

		this.connect(anchor, 'onclick', function () {
			input.value = '';
			this.onChangeInput(input, anchor);
			this.onDeleteInput(row);
		});
		var f = function () {
			this.onChangeInput(input, anchor);
		};
		this.connect(input, 'onchange', f);
		this.connect(input, 'onkeyup', f);
		this.connect(input, 'onclick', f);
		this.connect(input, 'onblur', function () {
			if (this.isInputEmpty(input)) {
				this.onDeleteInput(row);
			}
		});
		dojo.removeClass(row, 'HideElement');
		// insert before templates
		this.tableBodyNode.insertBefore(row, rows[rows.length - 2]);
		this._setAlternateClass();
	},

	isInputEmpty: function (input) {
		return input.value == '';
	},

	_changeErrorMessage: function (isValid, errorNode, inputNode) {
		if (!isValid) {
			var absolutePositionY = ($E(inputNode).getAbsolutePosition(dojo.body()).y + inputNode.offsetHeight);
			dojo.publish("uimessage/show", ["", errorNode.innerHTML, "Bubble", {
					typeClass: "Warning",
					sizeClass: "Small",
					x: $E(inputNode).getAbsolutePosition(dojo.body()).x,
					y: absolutePositionY
                }]);
		} else {
			dojo.publish("uimessage/hide", []);
		}
		return isValid;
	},

	onChangeInput: function (input, anchor) {
		if (!this.isInputEmpty(input) && dojo.hasClass(anchor, 'HideElement')) {
			dojo.removeClass(anchor, 'HideElement');
		}
		if (!this.allowDuplicates) {
			if (this.isInputEmpty(input)) {
				dojo.removeClass(input, 'DialogError');
			} else {
				//check if value only consists of whitespace chars
				var whitespaceCleared = input.value.replace(/\s/g, '');
				if (whitespaceCleared.length == 0) {
					dojo.addClass(input, 'DialogError');
				} else {
					dojo.removeClass(input, 'DialogError');
					var value = input.value;
					var lcValue = value.toLowerCase();
					var oldValues = dojo.filter(this._oldValues, function (el) {
						return el.toLowerCase() == lcValue;
					});
					if (oldValues.length) {
						dojo.addClass(input, 'DialogError');
					} else {
						var inputs = dojo.filter(this.getInputs(), function (el) {
							return input != el && lcValue == el.value.toLowerCase();
						});
						this._changeErrorMessage(inputs.length == 0, this.DuplicateAttributeValueAlias, input);
						if (inputs.length != 0) {
							dojo.addClass(input, 'DialogError');
						}
					}
				}
			}
		}
		this.reorgInputs();
	},

	onDeleteInput: function (row) {
		row.parentNode.removeChild(row);
		this.reorgInputs();
	},

	reorgInputs: function () {
		var countEmptyRows = 0;
		var rows = this.rows();
		dojo.forEach(rows, function (row) {
			if (!dojo.hasClass(row, 'HideElement')) {
				var input = this.getInput(row);
				if (input === undefined) {
					return;
				}
				if (this.isInputEmpty(input)) {
					countEmptyRows++;
				} else {
					input.name = this.newInputNamePrefix + this._attributeCounter;
				}
			}
		}, this);
		if (this.autoEmptyRow && countEmptyRows == 0) {
			this.addNewRow();
		}
		this._setAlternateClass();
		//need little timeout to set existing rows correct
		window.setTimeout(dojo.hitch(this, function () {
			this.enableNextButton();
		}), 1);
	},

	_onLocalizedClick: function () {
		this.isLocalized = this.localizableNode.elementNode.checked;
		this.typePackageNode.value = (this.isLocalized ? "PreDefLocalizedString" : "PreDefString");
	},

	_onIsUsedClick: function () {
		if (this.isUsedFormNode.elementNode.checked) {
			// hide text in information element
			jq(this.isUsedFormNode.elementNode).closest('div').children('p:first').slideUp(500);
			dojo.removeClass(this.tableBodyNode.parentNode, 'HideElement');
			this.isUsedValueNode.value = "1";
			var isAllreadyInside = false;
			for (var i = 0, iLength = this._widgetsOfClass.length; i < iLength; i++) {
				if (this._widgetsOfClass[i] == this) {
					isAllreadyInside = true;
				}
			}
			if (!isAllreadyInside) {
				$A(this._widgetsOfClass).push(this);
			}
		} else {
			// show text in information element
			jq(this.isUsedFormNode.elementNode).closest('div').children('p:first').slideDown(500);
			dojo.addClass(this.tableBodyNode.parentNode, 'HideElement');
			this.isUsedValueNode.value = "0";
		}
		this._checkNextButton();
	},

	_checkNextButton: function () {
		var allWidgets = this._widgetsOfClass,
			validWidgets = dojo.filter(allWidgets, function (el) {
				return el.isValid();
			}),
			usedWidgets = dojo.filter(allWidgets, function (el) {
				return el.isInUse();
			}),
			valid = allWidgets.length === validWidgets.length,
			b = $$(this.nextButtonId);

		if (!valid || usedWidgets.length == 0) {
			if (b === undefined) {
				$(this.nextButtonId).disabled = "disabled";
			} else {
				b.disable();
			}
		} else {
			if (b === undefined) {
				$(this.nextButtonId).disabled = "";
			} else {
				b.enable();
			}
		}
	},

	_onChangeAttributeAlias: function () {
		var inputNode = this.attributeAliasNode;
		var value = inputNode.value;
		if (value == this.attributeAlias) {
			if (dojo.hasClass(inputNode, 'DialogError')) {
				dojo.removeClass(inputNode, 'DialogError');
				dojo.publish("uimessage/hide", []);
			}
			return;
		}
		// test if alias is empty
		var isOk = true;
		if (!this._changeErrorMessage(!this.isInputEmpty(inputNode), this.EmptyAttributeAlias, inputNode)) {
			isOk = false;
			dojo.addClass(inputNode, 'DialogError');
		}
		// test if xml complaint
		if (isOk) {
			if (!this._changeErrorMessage(epages.validate.string.isXMLAttribute(value), this.AttributeAliasNoXMLName, inputNode)) {
				isOk = false;
			}
		}
		// test duplicate alias
		var lcValue = value.toLowerCase();
		if (isOk) {
			var aliases = dojo.filter(this._widgetsOfClass, function (el) {
				return el.attributeAlias.toLowerCase() == lcValue;
			});
			if (!this._changeErrorMessage(aliases.length == 0, this.ProductAttributeExists, inputNode)) {
				isOk = false;
				dojo.addClass(inputNode, 'DialogError');
			}
		}
		if (isOk) {
			var aliases = dojo.filter(this._existingAttributes, function (el) {
				return el.toLowerCase() == lcValue;
			});
			if (!this._changeErrorMessage(aliases.length == 0, this.ProductAttributeExists, inputNode)) {
				isOk = false;
				dojo.addClass(inputNode, 'DialogError');
			}
		}
		if (isOk) {
			this.attributeAlias = value;
		}
		this.enableNextButton();
	},

	_onClickDeleteAttribute: function () {
		// remove from list
		var allWidgets = this._widgetsOfClass;
		epages.cartridges.de_epages.product.widget.VariationAttributeList.prototype._widgetsOfClass = [];
		dojo.forEach(allWidgets, function (el) {
			if (el == this) {
				return;
			}
			el.setAttributeCounter(this._widgetsOfClass.length);
			this._widgetsOfClass.push(el);
		}, this);
		this.enableNextButton();
		dojo.publish(this.id + '/onClickDeleteAttribute', [this]);
	},

	isValid: function () {
		//summary: check if current Attribute is valid
		//description: check if alias of attribute is defined, if values are set
		//and if there are no DialogErrors inside the inputs
		if (this.getInputs().length == 2 && this._oldValues.length == 0) {
			return false; // Boolean
		}
		if (this.attributeAlias == '') {
			return false;
		}
		if (dojo.hasClass(this.attributeAliasNode, 'DialogError')) {
			return false;
		}
		var invalidInputs = dojo.filter(this.getInputs(), function (el) {
			return dojo.hasClass(el, 'DialogError');
		});
		if (invalidInputs.length) {
			return false;
		}
		return true; // Boolean
	},

	isInUse: function () {
		//summary: check if current Attribute is used
		//description: check if variation will be created with this attribute
		if (!this.useAttribute()) {
			return false; // Boolean
		}
		return true; // Boolean
	},

	enableNextButton: function () {
		// summary: send message to enable next button (if validation is ok)
		dojo.publish("step1/checkNextButton", []);
	},

	useAttribute: function () {
		return this.isUsed || this.isUsedFormNode.elementNode.checked;
	},

	getValues: function () {
		var values = [];
		for (var i = 0, length = this._oldValues.length; i < length; i++) {
			values.push(this._oldValues[i]);
		}
		dojo.forEach(this.getInputs(), function (input) {
			if (!this.isInputEmpty(input)) {
				values.push(input.value);
			}
		}, this);
		return values;
	},

	hasNewAttributes: function () {
		var allWidgets = epages.cartridges.de_epages.product.widget.VariationAttributeList.prototype._widgetsOfClass;
		if (allWidgets.length == 0) {
			return false;
		}
		var newWidgets = dojo.filter(allWidgets, function (el) {
			return el.isNew;
		});
		return newWidgets.length > 0;
	},

	getAttributeCounter: function () {
		return this._attributeCounter;
	}

});