//the initializer below will not init autoComplete fields
//auto-complete fields must be individually initialized to define a data source
$(document).ready(function() {
    if (($('.hiddenPressRelease')) && ($('.hiddenPressRelease').length > 0)) {
        //if press release page don't execute the scripts
    }
    else {
        $("div.ui-field-select").fieldSelect();
    }
});

/*########################################################*/
/*-------------- text field/(pseudo-)select ui control --------------------*/

(function($) {
    // constructor
    function FieldSelect(root, conf) {
        // Private fields ------------------------------------------------------------------

        var $root = $(root), //maps to div.ui-field-select
			_domElem = $root[0],
			_self = this,
			$wrapper,
			$selectMenu,
			$selectList,
			$arrowBtn,
			$hintLabel,
			$textField,
			_bgImg,
			_bgCol,
			_listeners = [],
        //customizable content dropdown
			$selectedContentWrapper = null,
        //$listItems,
			_fieldSelectId,
        //_isSaveable = false,

			_isHintField,
			_isCustomContentDropdown,
			_isAutoComplete,

			 _minChars,

			$opts = {
			    minChars: 2,
			    yOffset: 2,
			    //autocomplete
			    fieldRef: '.autocomplete_term',
			    minLength: 2,
			    dataSource: null //must be passed in for autocomplete fields to initialize
			};
        $.extend($opts, conf);

        // Public methods ------------------------------------------------------------------

        $.extend(_self, {
            onFieldClick: function(evt) {
                //close other menus
                $("div.ui-field-select").each(function() {
                    var $that = $(this);
                    if (!$that.equals($root)) {
                        //alert("$that.data(fieldSelect): " + $that.data("fieldSelect"));
                        $that.data("fieldSelect").resetList();
                    }
                })

                if (_isAutoComplete == false) {
                    if ($selectMenu.is(":visible")) {
                        hideList();
                    } else {
                        prepList();
                    }
                }
            },
            addEventListener: function($obj, eventName) {
                _listeners.push($obj);
            },
            clear: function() {
                $textField.val('');
                if (_isHintField == true) {
                    $hintLabel.data("inFieldLabel").checkForEmpty();
                }
            },
            updateList: function(dataArray) {
                if ($selectList.length > 1) {
                    $selectList.parent().find('ul:not(:first)').remove();
                    $selectList = $($selectList[0]);
                }
                $selectList.html("");
                for (var i = 0; i < dataArray.length; i++) {
                    $selectList.append('<li>' + dataArray[i] + '</li>');
                }
            },
            onItemClick: function(li) {
                _self.setSelectedItem(li);
            },
            setSelectedItem: function(li, force) {
                var $li = $(li);
                if (!$li.hasClass("selected") || force == true) {
                    $selectMenu.find("li.selected").removeClass("selected");

                    $li.addClass("selected");

                    //update the value of the field; clone so we can remove hidden item data for customizable content dropdowns
                    var $selectedValue = $li.clone();
                    $selectedValue.find("span.list-item-data").remove();
                    var newVal = $.trim($selectedValue.text());
                    if (newVal != $textField.val()) {
                        $textField.val(newVal);
                            dispatchEvent("onGtaaSelectChange", { text: newVal, targetClass: $textField[0].className });
                    }

                    //update the associated content wrapper for customizable content dropdowns
                    if (_isCustomContentDropdown == true) {
                        $selectedContentWrapper.html($li.find("span.list-item-data").html() || $.trim($li.text()));
                    }

                    //save selected option, if applicable
                    if (_fieldSelectId != null && $li.attr("id")) {
                        $.cookie(_fieldSelectId, $li.attr("id"), { expires: 300, path: '/' });
                    }
                }

                hideList();
            },
            setSelectedByValue: function(value) {
                var regex = new RegExp(value, "i");
                var items = $selectMenu.find('li');
                for (var i = 0; i < items.length; i++) {
                    var isMatch = regex.test($(items[i]).text());
                    if (isMatch) {
                        _self.setSelectedItem(items[i]);
                        break;
                    }
                }

            },
            setSelected: function(index) {
                var items = $selectMenu.find('li');
                _self.setSelectedItem(items[index]);
            },
            getSelectedValue: function() {
                var value;
                var $li = $selectMenu.find('li.selected');
                value = $li.find("span.list-item-data").html() || $li.html();
                return value;
            },
            getSelectedItem: function() {
                return $selectMenu.find('li.selected') || null;
            },
            showList: function() {
                $selectMenu.show();
                if (_isAutoComplete == false) {
                    $(document).bind('mousedown', onDocumentMousedown);
                }
            },
            resetList: function() {
                hideList();
            },
            showAcList: function() {
                prepList();
            },
            hideAcList: function() {
                hideList();
            },
            setAutoCompleteSource: function(srcArray) {
                //set jQuery ui plugin option (see "http://jqueryui.com/demos/autocomplete/#method-option")
                $($opts.fieldRef).gtaa_complete("option", "source", srcArray);
            }
        });

        // Private methods -----------------------------------------------------------------

        function init() {
            //instance variables
            _isHintField = $root.find("label").length > 0
            _isCustomContentDropdown = $root.siblings("div.selected-content-wrapper").length > 0;
            _isAutoComplete = $root.hasClass('ui-field-select-autocomplete');

            //must have data source for auto-complete field
            if (_isAutoComplete == true && $opts.dataSource == null) {
                return;
            }

            //display objects
            //-common
            $wrapper = $root.parents("div.ui-field-select-wrapper");
            $arrowBtn = $root.find("span.ui-icon");
            $textField = $root.find("input[type=text]");
            //-in-field hints
            if (_isHintField == true) {
                $hintLabel = $root.find("label");
            }
            //-customizable content dropdown
            if (_isCustomContentDropdown == true) {
                $selectedContentWrapper = $root.siblings("div.selected-content-wrapper"); //contentWrapper.length > 0 ? contentWrapper : null;
            }
            //-common with type-specific behaviour
            initSelectMenu();

            if (_isAutoComplete == false) {
                initDisabledFieldHotSpot();

                //events
                $root.click(	//clicking the in-field label fires 2 click events, so we ignore the one attached to the label 
				function(evt) {
				    if (!($(evt.target).is("label"))) {
				        $textField.focus();
				        _self.onFieldClick(evt);
				    }
				}).mousedown(function(evt) {
				    evt.stopPropagation();
				});
            }
        };

        function initSelectMenu() {
            $selectMenu = $wrapper.find("div.ui-select-list").hide().appendTo($("body"));
            _bgImg = $selectMenu.css("background-image");
            _bgCol = $selectMenu.css("background-color");

            if (_isAutoComplete == true) {
                $($opts.fieldRef).gtaa_complete({
                    minLength: $opts.minLength,
                    gtaaFieldSelectReference: _self,
                    appendTo: $selectMenu.find('.list-wrapper')[0],
                    source: $opts.dataSource
                });

            } else {

                //handlers (stopPropagation to manage closing list when user clicks outside of it)
                $selectMenu.mousedown(
					function(evt) {
					    evt.stopPropagation();
					}
				);
                $selectMenu.click(
					function(evt) {
					    var _li = $(evt.target).is('li') ? evt.target : $(evt.target).parent('li')[0];
					    if (_li != null) {
					        _self.onItemClick(_li);
					    } else {
					        hideList();
					    }
					}
				);

                $selectList = $selectMenu.find("ul");

                //if there's no in-field hint, select a default option (custom content dropdown will show the saved value)
                if (!_isHintField) {
                    initSelectedContent();
                }
            }
        }

        function initSelectedContent() {
            if (_isCustomContentDropdown == true) {
                //set id for saving and check to see if the user saved an option before
                var regex = /field-select-id-[^\s]*/;
                _fieldSelectId = regex.exec($wrapper[0].className)[0] || null;

                var lastSavedItem = $selectMenu.find("li#" + $.cookie(_fieldSelectId));
                _self.setSelectedItem(lastSavedItem.length > 0 ? lastSavedItem[0] : $selectList.find("li")[0]);
            } else {
                var selectedOption = $selectMenu.find("li.selected");
                var defaultOption = selectedOption.length > 0 ? selectedOption[0] : $selectList.find("li")[0];
                _self.setSelectedItem(defaultOption, true);
            }
        };

        function initDisabledFieldHotSpot() {
            //layers a helper div over "disabled" fields to capture clicks and avoid the cursor showing at all
            //we need to fake this disable behaviour since IE doesn't allow us to override the look of real disabled fields with styles
            if ($textField.hasClass("disabled")) {
                $blocker = $("<div></div>");
                $blocker.css({
                    "position": "absolute",
                    "top": "0px",
                    "left": "0px",
                    "width": $textField.outerWidth() + "px",
                    "height": $textField.outerHeight() + "px"
                });
                $root.find("div.formHint-field-group").append($blocker);

                $textField.focus(function() {
                    var $me = $(this);
                    setTimeout(function() { $me.blur(); }, 20); //slight delay to get around firefox not hiding the field cursor when we blur immediately
                });
            }
        }

        //display ------------------------------------------------------------------
        function prepList() {
            arrowUp();
            //if (_isAutoComplete == false) {
            positionList();
            //}
            _self.showList();
        }

        function hideList() {
            arrowDown();

            $selectMenu.hide();
            //if (_isAutoComplete == false) {
            $selectMenu.offset({
                top: 0,
                left: -500
            });
            //}
            if (_isAutoComplete == false) {
                $(document).unbind('mousedown', onDocumentMousedown);
            }
            if (_isHintField == true) {
                $hintLabel.data("inFieldLabel").checkForEmpty();
            }
        }

        function positionList() {
            //match rounded corners
            if ($.browser.msie == true) {
                $selectMenu.removeClass("ui-corner-all ui-big-corner-all");
            } else if ($root.hasClass("ui-big-corner-all")) {
                $selectMenu.removeClass("ui-corner-all");
                $selectMenu.addClass("ui-big-corner-all");
            }
            $selectMenu.css(
				{
				    "position": "absolute",
				    "min-width": ($root.outerWidth() - ($.parseCleanInt($selectMenu.css("padding-left")) * 2)) + "px",
				    "max-width": ($root.outerWidth() - ($.parseCleanInt($selectMenu.css("padding-left")) * 2)) + "px"
				}
			);
            //ie7 doesn't scale the contained div to fit when the list div is set above, so we do it manually
            if ($.isIe7()) {
                $selectMenu.find("div.list-wrapper").css({
                    "min-width": ($root.outerWidth() - ($.parseCleanInt($selectMenu.css("padding-left")) * 2)) + "px",
                    "max-width": ($root.outerWidth() - ($.parseCleanInt($selectMenu.css("padding-left")) * 2)) + "px"
                });
            }

            //ie "blinks" the list background at top/left of the document for a split second before showing, so clear/reset those properties
            if ($.browser.msie) {
                $selectMenu.css({
                    "background-image": "none",
                    "background-color": "transparent"
                });
            }

            var targetTop = $root.offset().top + $root.outerHeight() + $opts.yOffset;
            var targetLeft = $root.offset().left;
            $selectMenu.css(
				{
				    "top": targetTop + "px",
				    "left": $root.offset().left + "px"
				}
			);

            //see above
            if ($.browser.msie) {
                $selectMenu.css({
                    "background-image": _bgImg,
                    "background-color": _bgCol
                });
            }
        }

        function arrowUp() {
            $arrowBtn.removeClass("ui-arrow-down").addClass("ui-arrow-up");
        }

        function arrowDown() {
            $arrowBtn.removeClass("ui-arrow-up").addClass("ui-arrow-down");
        }

        //events ------------------------------------------------------------------
        function dispatchEvent(evtType, dataObj) {
            setTimeout(
				function() {
				    delayedDispatch(evtType, dataObj);
				},
				50 //tiny delay to give the screen a chance to update
			);
        }

        function delayedDispatch(evtType, dataObj) {
            for (var i = 0; i < _listeners.length; i++) {
                _listeners[i].trigger(evtType, dataObj);
            }
        }

        function onDocumentMousedown() {
            hideList();
        }

        // Initialization ------------------------------------------------------------------

        init();
    };

    // jQuery plugin implementation
    $.fn.fieldSelect = function(conf) {
        //defaults
        var opts = {
    };

    $.extend(opts, conf);

    this.each(function() {
        var $instance = new FieldSelect(this, opts);
        $(this).data("fieldSelect", $instance);
    });

    return this;
};
})(jQuery);
