/*
* INFORMATION
* ---------------------------
* Owner: jquery.webspirited.com
* Developer: Matthew Hailwood
* ---------------------------
*
* CHANGELOG:
* ---------------------------
* 1.1
* Fixed bug 01
* 1.2
* Added select option
* * hidden select so tags may be submitted via normal form.
* 1.3
* Fixed bug 02
* 1.4
* Fixed bug 03
* Fixed bug 04
*
* ---------------------------
* Bug Fix Credits:
* --
* * Number: 01
* * Bug: Clicking autocomplete option does not add it to the array
* * Name: Ed <tastypopsicle.com>
* --
* * Number: 02
* * Bug: Unable to give select a name
* * Name: Ed <tastypopsicle.com>
* --
* * Number 03
* * Bug: reference to incorrect variable (tagArray vs tagsArray)
* * Name: claudio <unknown>
* --
* * Number 04
* * Bug: console.log() left in code
* * Name: claudio <unknown>
*/

(function($) {
    $.widget("ui.tagit", {

        // default options
        options: {
            tagSource: [],
            triggerKeys: ['enter', 'space', 'comma', 'tab'],
            initialTags: [],
            minLength: 1,
            select: false,
            allowNewTags: true,
            emptySearch: true // empty search on focus

        },

        _keys: {
            backspace: [8],
            enter: [13],
            space: [32],
            comma: [44,188],
            tab: [9]
        },

        //initialization function
        _create: function() {

            var self = this;
            this.tagsArray = [];
            this.timer = null;

            //add class "tagit" for theming
            this.element.addClass("tagit");

            //add any initial tags added through html to the array
            this.element.children('li').each(function() {
             var tagValue = $(this).attr('tagValue');
                self.options.initialTags.push(
                 tagValue ? {label: $(this).text(), value: tagValue} : $(this).text()
                );
            });

            //add the html input
            this.element.html('<li class="tagit-new"><input class="tagit-input" type="text" /></li>');

            this.input = this.element.find(".tagit-input");

            //setup click handler
            $(this.element).click(function(e) {
                if ($(e.target).hasClass('tagit-close')) {
                    // Removes a tag when the little 'x' is clicked.
                 var parent = $(e.target).parent();
                    parent.remove();
                    var tagValue = parent.attr('tagValue');
                    if (tagValue) {
                     self._popTag(null, tagValue);
                    } else {
var text = parent.text();
self._popTag(text.substr(0, text.length - 1));
                    }
                }
                else {
                    self.input.focus();
                    if(self.options.emptySearch && $(e.target).hasClass('tagit-input') && self.input.val() == '' && self.input.autocomplete != undefined) {
                     self.input.autocomplete('search');
                    }
                }
            });

            //setup autocomplete handler
            var os = this.options.select;
            this.options.appendTo = this.element;
            this.options.source = this.options.tagSource;
            this.options.select = function(event, ui) {
                clearTimeout(self.timer);
                if (ui.item.label === undefined)
                 self._addTag(ui.item.value);
                else
                 self._addTag(ui.item.label, ui.item.value);
                return false;
            }
            var inputBox = this.input;
            this.options.focus = function(event, ui) {
             //if (ui.item.label !== undefined && /^key/.test(event.originalEvent.type)) {
             //inputBox.val(ui.item.label);
             //inputBox.attr('tagValue', ui.item.value);
             return false;
            // }
            }
            this.input.autocomplete(this.options);
            this.options.select = os;

            //setup keydown handler
            this.input.keydown(function(e) {
                var lastLi = self.element.children(".tagit-choice:last");
                if (e.which == self._keys.backspace)
                    return self._backspace(lastLi);

                if (self._isInitKey(e.which)) {
                    e.preventDefault();
                    if (self.options.allowNewTags && $(this).val().length >= self.options.minLength) {
                        self._addTag($(this).val());
                    }
                    else if (!self.options.allowNewTags){
                    self.input.val("");
                    }
                }

                if (lastLi.hasClass('selected'))
                    lastLi.removeClass('selected');

                self.lastKey = e.which;
            });

            //setup blur handler
            this.input.blur(function(e) {
                self.currentLabel = $(this).val();
                self.currentValue = $(this).attr('tagValue');
                if(self.options.allowNewTags) {
                    self.timer = setTimeout(function(){
                        self._addTag(self.currentLabel, self.currentValue);
                        self.currentValue = '';
                        self.currentLabel = '';
                    }, 400);
                }
                $(this).val('').removeAttr('tagValue');
                return false;
            });

            //define missing trim function for strings
            String.prototype.trim = function() {
                return this.replace(/^\s+|\s+$/g, "");
            };

            if (this.options.select) {
                this.element.after('<select class="tagit-hiddenSelect" name="'+this.element.attr('name')+'" multiple="multiple"></select>');
                this.select = this.element.siblings('.tagit-hiddenSelect');
            }
            this._initialTags();

        },

        _popSelect: function(label, value) {
         this.select.children('option[value="' + (value === undefined ? label : value) + '"]').remove();
            this.select.change();
        }
        ,

        _addSelect: function(label, value) {
            this.select.append('<option selected="selected" value="'
             + (value === undefined ? label : value)
             + '">' + label + '</option>');
            this.select.change();
        }
        ,

        _popTag: function(label, value) {
            if (label === undefined) {
                label = this.tagsArray.pop();
                if (typeof (label) == 'object') {
                 value = label.value;
                 label = label.label;
                }
            } else {
             var index;
             if (value === undefined) {
             index = $.inArray(label, this.tagsArray);
             index = (index == -1 ? this.tagsArray.length - 1 : index);
             } else {
             index = this.tagsArray.length - 1;
             for (var i in this.tagsArray) {
             if (this.tagsArray[i].value == value) {
             index = i;
             break;
             }
             }
             }
                this.tagsArray.splice(index, 1);
            }
            if (this.options.select)
                this._popSelect(label, value);
        }
        ,

        _addTag: function(label, value) {
            this.input.val("");
            label = label.replace(/,+$/, "");
            label = label.trim();
            if (label == "" || this._exists(label, value))
                return false;

            var tag = "";
            tag = '<li class="tagit-choice"'
             + (value !== undefined ? ' tagValue="' + value + '"' : '')
             + '>' + label + '<a class="tagit-close">x</a></li>';
            $(tag).insertBefore(this.input.parent());
            this.input.val("");
            this.tagsArray.push(value === undefined ? label : {label: label, value: value});
			//temp hack to hide the suggestions after tag is added(enter key press)
			$(".ui-autocomplete").hide();
            if (this.options.select)
                this._addSelect(label, value);
            return true;
        }
        ,

        _exists: function(label, value) {
		return false;
         if (this.tagsArray.length == 0) {
         return false;
         }
    
         if (value === undefined) {
         for(var ind in this.tagsArray) {
     if (label == this.tagsArray[ind] || label == this.tagsArray[ind].label)
     return true;
     }
         } else {
     for(var ind in this.tagsArray) {
     if (value == this.tagsArray[ind].value)
     return true;
     }
     }
            return false;
        }
        ,

        _isInitKey : function(keyCode) {
            var keyName = "";
            for (var key in this._keys)
         if ($.inArray(keyCode, this._keys[key]) != -1)
         keyName = key;
        
            if ($.inArray(keyName, this.options.triggerKeys) != -1)
                return true;
            return false;
        }
        ,

        _removeTag: function() {
            this._popTag();
            this.element.children(".tagit-choice:last").remove();
        }
        ,

        _backspace: function(li) {
            if (this.input.val() == "") {
                // When backspace is pressed, the last tag is deleted.
                if (this.lastKey == this._keys.backspace) {
                    this._popTag();
                    li.remove();
                    this.lastKey = null;
                } else {
                    li.addClass('selected');
                    this.lastKey = this._keys.backspace;
                }
            }
            return true;
        }
        ,

        _initialTags: function() {
            var input = this;
            if (this.options.initialTags.length != 0) {
                $(this.options.initialTags).each(function(i, element){
                 if (typeof (element) == "object")
                 input._addTag(element.label, element.value);
                 else
                 input._addTag(element);
                });
            }
        }
        ,

        tags: function() {
            return this.tagsArray;
        }
        ,

        destroy: function() {
            $.Widget.prototype.destroy.apply(this, arguments); // default destroy
            this.tagsArray = [];
        }
        ,
        
        reset: function() {
         this.element.find(".tagit-choice").remove();
         this.tagsArray = [];
         if (this.options.select) {
         this.select.children().remove();
         this.select.change();
         }
         this._initialTags();
        }

    });
})(jQuery);



