/*
 * Copyright 2004-2014 ICEsoft Technologies Canada Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS
 * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
ice.ace.TextEntry = function(id, cfg) {
    var inputId = id + "_input";
    this.id = id;
    this.cfg = cfg;
    this.jqId = ice.ace.escapeClientId(id) + " input.ui-textentry";
    this.jq = ice.ace.jq(this.jqId);
    var self = this;

    if (cfg.autoTab) {
		this.attachAutoTabEvents();
    }
    if (cfg.embeddedLabel) {
		if (!this.cfg.secret) {
			document.getElementById(inputId).submitOnEnter = 'disabled';
			ice.ace.jq(ice.ace.escapeClientId(inputId)).on('keypress keydown keyup', function(e) {
				if (!this.value) {
					this.submitOnEnter = 'disabled';
					if (e.which === 13) {
						e.preventDefault();
						e.stopPropagation();
						return false;
					}
				} else {
					this.submitOnEnter = '';
				}
			});
		}
		this.attachEmbeddedLabelEvents();
    } else {
		if (this.cfg.secret) {
			this.changeType('password');
			if (cfg.autoTab) this.attachAutoTabEvents();
		}
	}
    this.jq.blur(function() {
        ice.setFocus();
    });
    if (cfg.behaviors) this.attachBehaviors();
    ice.onElementUpdate(inputId, function() {
        ice.ace.destroy(id);
    });
};

ice.ace.TextEntry.prototype.attachAutoTabEvents = function() {
	this.jq.keypress(
		function(e) {
			var curLength = this.value.length + 1, maxLength = this.maxLength;
			var nextTabElement = ice.ace.TextEntry.nextTabElement(this);
			/*
			 console.log("id: ", this.id);
			 console.log("value: ", this.value);
			 console.log("value.length: ", this.value.length);
			 console.log("maxLength: ", maxLength);
			 console.log("charCode: ", e.charCode);
			 console.log("keyCode: ", e.keyCode);
			 console.log("which: ", e.which);
			 //            console.dir(e);
			 */
			if (curLength < maxLength || !nextTabElement) {
				return;
			}
			if (e.which < 32 || e.charCode == 0 || e.ctrlKey || e.altKey) {
				return;
			}
			e.preventDefault();
			if (curLength == maxLength) {
				this.value += String.fromCharCode(e.which);
			}
			/*
			 console.log("value: ", this.value);
			 console.log("value.length: ", this.value.length);
			 */
			nextTabElement.focus();
		}
	);
};

ice.ace.TextEntry.prototype.attachEmbeddedLabelEvents = function() {
	var self = this;
    var inputId = this.id + "_input";
    var labelName = this.id + "_label";
	this.jq.focus(
		function() {
			var input = ice.ace.jq(this);
			if (input.attr("name") == labelName) {
				input.attr({name: inputId});
				input.val("");
				input.removeClass("ui-input-label-infield");
				if (self.cfg.secret) {
					self.changeType('password');
					if (self.cfg.autoTab) self.attachAutoTabEvents();
					if (self.cfg.embeddedLabel) {
						document.getElementById(inputId).submitOnEnter = 'disabled';
						ice.ace.jq(ice.ace.escapeClientId(inputId)).on('keypress keydown keyup', function(e) {
							if (!this.value) {
								this.submitOnEnter = 'disabled';
								if (e.which === 13) {
									e.preventDefault();
									e.stopPropagation();
									return false;
								}
							} else {
								this.submitOnEnter = '';
							}
						});
						self.attachEmbeddedLabelEvents();
					}
					if (self.cfg.behaviors) self.attachBehaviors();
					self.jq.focus();
				}
			}
		}).blur(
		function() {
			ice.setFocus('');
			var input = ice.ace.jq(this);
			if (ice.ace.jq.trim(input.val()) == ""
				&& !(self.cfg.behaviors && self.cfg.behaviors.blur)) {
				input.attr({name: labelName});
				input.val(self.cfg.embeddedLabel);
				input.addClass("ui-input-label-infield");
				if (self.cfg.secret) {
					self.changeType('text');
					if (self.cfg.autoTab) self.attachAutoTabEvents();
					if (self.cfg.embeddedLabel) self.attachEmbeddedLabelEvents();
					if (self.cfg.behaviors) self.attachBehaviors();
				}
			}
		});
};

ice.ace.TextEntry.prototype.attachBehaviors = function() {
	var self = this;
    var inputId = this.id + "_input";
	ice.ace.jq.each(this.cfg.behaviors, function(name, behavior) {
		if (name == 'charCount') {
			var target = document.getElementById(inputId);
			behavior.currLength = function() {
				return target.value.length;
			};
			behavior.charsRemaining = function() {
				return target.maxLength - target.value.length;
			};
			if (document.attachEvent) {
				//IE 7,8,9 handling -- backspace and delete keypresses do not trigger 'input' events
				self.jq.on('input', function (e) {
					if (e.target.value.length <= e.target.maxLength) {
						e.cancelBubble = true;
						ice.ace.ab(behavior);
					}
				});
				self.jq.on('keyup', function (e) {
					if (e.target.value.length <= e.target.maxLength) {
						ice.ace.ab(behavior);
					}
				});
			} else {
				self.jq.on('input', function (e) {
					ice.ace.ab(behavior);
				});
			}
		} else {
			self.jq.on(name, function () {
				ice.ace.ab(behavior);
			});
		}
	});
};

ice.ace.TextEntry.prototype.changeType = function(type) {
	var newInput = '<input';
	ice.ace.jq.each(this.jq.get(0).attributes, function(i, attr) {
		if (attr.name == 'type' || attr.name == 'value') return true;
		newInput += ' ' + attr.name + '="' + attr.value + '"';
	});
	newInput += ' type="'+type+'" value="'+this.jq.val()+'" />';
	this.jq.replaceWith(newInput);
    this.jq = ice.ace.jq(this.jqId);
};

// Original code copied from http://stackoverflow.com/a/7329696
// See comments at http://jira.icesoft.org/browse/ICE-7824?focusedCommentId=39755&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_39755
ice.ace.TextEntry.nextTabElement = function(currElement) {
    // if we haven't stored the tabbing order
    if (!currElement.form.tabOrder) {

        var els = currElement.form.elements,
                ti = [],
                rest = [];

        // store all focusable form elements with tabIndex > 0
        for (var i = 0, il = els.length; i < il; i++) {
            if (els[i].tabIndex > 0 &&
                    !els[i].disabled &&
                    !els[i].hidden &&
                    !els[i].readOnly &&
                    els[i].type !== 'hidden') {
                ti.push(els[i]);
            }
        }

        // sort them by tabIndex order
        ti.sort(function(a,b){ return a.tabIndex - b.tabIndex; });

        // store the rest of the elements in order
        for (i = 0, il = els.length; i < il; i++) {
            if (els[i].tabIndex == 0 &&
                    !els[i].disabled &&
                    !els[i].hidden &&
                    !els[i].readOnly &&
                    els[i].type !== 'hidden') {
                rest.push(els[i]);
            }
        }

        // store the full tabbing order
        currElement.form.tabOrder = ti.concat(rest);
    }

    // find the next element in the tabbing order and focus it
    // if the last element of the form then blur
    // (this can be changed to focus the next <form> if any)
    for (var j = 0, jl = currElement.form.tabOrder.length; j < jl; j++) {
        if (currElement === currElement.form.tabOrder[j]) {
            if (j+1 < jl) {
//                        $(this.form.tabOrder[j+1]).focus();
                return currElement.form.tabOrder[j+1];
            } else {
//                        $(this).blur();
            }
        }
    }
};