﻿/****************************************************************************************
* Form Style Javascript file
* 
* Adds style-ability and extends functionality of form elements
*/
/****************************************************************************************
 * Brighthouse initialization code
 */
$(document).ready(function() {
    // Dynamically load css
    $('head').addStyleSheet(cmsBaseURL + "/static/stylesheets/jquery.form.style.css");
    // instantiate styled select boxes
    $('select:not(.unstyled,:hidden)').sSelect({
        ddMaxHeight: 260,
        ddMinWidth: 139,
        ddMaxWidth: 310,
        ulWidthOffset : 8
        });
    // instantiates solo-input validation 
    $('.input-solo').restrict('input[name=zipcode]','zipcode')
    // instantiates select validation 
    $('form[name=area_form]').restrict('select','select')
});
/**************************************************
* Establishes validation requirements for form elements.
*/
if (jQuery) (function($) {
    jQuery.extend(jQuery.fn, {
        restrict: function(el,type) {
            this.each(function() {
                // establish references
                var $this = $(this);
                var button = $this.find('button[type=submit]');
                if(!button && $this.hasClass('input-solo')){ 
                    button = $this.find('a');
                }
                var restrictable = $this.find(el);
                if (restrictable.length == 0) return;
                switch (type) {
                    case 'select':
                        var select = restrictable;
                        disableBtn(button);
                        // on change, enable button if value selected
                        select.change(function() {
                            var value = $(this).find('option[selected]').val();
                            if (value) enableBtn(button);
                            else disableBtn(button);
                        });
                        break;
                    // ZIPcode solo-input      
                    case 'zipcode':
                        var input = restrictable;
                        var value = input.val();
                        // prevent autofill
                        input.attr('autocomplete', 'off');
                        // allow only numbers to be input
                        numbersOnly(input);
                        minCharacters(input, button, 5)
                        // only allow submit when at least 5 sharacters have been entered
                        input.keyup(function(e) {
                            if (e.keyCode == 16) input.attr('shiftactive', 'false')
                            minCharacters(input, button, 5)
                            if (e.keyCode == 13) {
                                button.trigger('click');
                                return false;
                            };
                        });
                        input.change(function(e) { minCharacters(input, button, 5) });
                        break;
                    default:
                        // minCharacters(input, button, 1);
                        break;
                }
            });
            function minCharacters(input, button, num) {
                var value = input.val();
                if (value.length >= num) enableBtn(button)
                else disableBtn(button)
                return;
            }
            function numbersOnly(input) {
                input.keydown(function(e) {
                    var key = e.keyCode;
                    var shiftactive = input.attr('shiftactive');
                    // if not a number or a special key
                    if (key > 57 && (key < 96 || key > 105) || shiftactive == 'true') {
                        return false;
                        // if shift is active
                    } else if (key == 16) {
                        input.attr('shiftactive', 'true')
                    }
                    return true;
                });
            }
            function disableBtn(btn) {
                var btnclass = btn.attr('class');
                if (btnclass.indexOf('-inactive') >= 0) return;
                if (btn.tagName == 'a'){
                    // Disable click action
                }else{
                    btn.attr('class', btnclass + '-inactive');
                    btn.attr('disabled', 'disabled')
                }
            }
            function enableBtn(btn) {
                var btnclass = btn.attr('class');
                btn.attr('class', btnclass.replace('-inactive', ''))
                if (btn.tagName == 'a'){
                    // enable click
                }else{
                    btn.attr('disabled', '')
                }
            }
        }
    });
})(jQuery);
/********************************************************************************************************************************************************************************
* Brighthouse Development notes:
*
* 3/8/2010 - JMP
* Added form validaion and enable/disable submit for solo-input form elements.
* 
* 11/4/2009 - JMP
* Created functionality to support min/max defined flexible width for dropdown. 
* Fixed auto-scroll and corrected negative margin positioning error.
*
* 10/28/2009 - JMP 
* Adjusted dynamic height code to set the UL top position to 'auto'.
* See "function newUlPos()"
*
* 9/03/2009 - JMP 
* Adjusted dynamic height code to remove superfluous pixels.
* See "function newUlPos()"
*/ 
// Largely based on the following plugin:
/****************************************************************************************
* Stylish Select 0.3 - plugin to replace a select drop down with a stylable unordered list
* http://scottdarby.com/
* Copyright (c) 2009 Scott Darby
*
* Requires: $ 1.3
*
* Licensed under the GPL license:
* http://www.gnu.org/licenses/gpl.html
*/

(function($) {
    //add class of js to html tag
    $('html').addClass('js');
    //create cross-browser indexOf
    Array.prototype.indexOf = function(obj, start) {
        for (var i = (start || 0); i < this.length; i++) {
            if (this[i] == obj) {
                return i;
            }
        }
    }
    //utility methods
    $.fn.extend({
        getSetSSValue: function(value) {
            if (value) {
                //set value and trigger change event
                $(this).val(value).change();
                return this;
            } else {
                return selText = $(this).find(':selected').text();
            }
        },
        resetSS: function() {
            $this = $(this);
            $this.next().remove();
            //unbind all events and redraw
            $this.unbind().sSelect();
        }
    });
    $.fn.sSelect = function(options) {
        return this.each(function() {
            var defaults = {
                defaultText: 'Please select',
                animationSpeed: 0, //set speed of dropdown
                ddMaxHeight: null, //set css max-height value of dropdown
                ddMinWidth: 100,
                ddMaxWidth: 300,
                marginFix: 0
            };
            //initial variables
            var opts = $.extend(defaults, options),
                $input = $(this),
                $containerDivText = $('<div class="selectedTxt"></div>'),
                $containerDiv = $('<div class="newListSelected" tabindex="0"></div>'),
                $newUl = $('<ul class="newList"></ul>'),
                itemIndex = -1,
                currentIndex = -1,
                keys = [],
                prevKey = false,
                newListItems = '',
                prevented = false;
            //build new list
            $containerDiv.insertAfter($input);
            $containerDivText.prependTo($containerDiv);
            $newUl.appendTo($containerDiv);
            $input.hide();
            //test for optgroup
            if ($input.children('optgroup').length == 0) {
                $input.children().each(function(i) {
                    var option = $(this).text();
                    //add first letter of each word to array
                    keys.push(option.charAt(0).toLowerCase());
                    if ($(this).attr('selected') == true) {
                        opts.defaultText = option;
                        currentIndex = i;
                    }
                    newListItems += '<li>' + option + '</li>';
                });
                //add new list items to ul
                $newUl.html(newListItems);
                newListItems = '';
                //cache list items object
                var $newLi = $newUl.children();
            } else { //optgroup
                $input.children('optgroup').each(function(i) {
                    var optionTitle = $(this).attr('label'),
                        $optGroup = $('<li class="newListOptionTitle">' + optionTitle + '</li>');
                    $optGroup.appendTo($newUl);
                    var $optGroupList = $('<ul></ul>');
                    $optGroupList.appendTo($optGroup);
                    $(this).children().each(function() {
                        ++itemIndex;
                        var option = $(this).text();
                        //add first letter of each word to array
                        keys.push(option.charAt(0).toLowerCase());
                        if ($(this).attr('selected') == true) {
                            opts.defaultText = option;
                            currentIndex = itemIndex;
                        }
                        newListItems += '<li>' + option + '</li>';
                    })
                    //add new list items to ul
                    $optGroupList.html(newListItems);
                    newListItems = '';
                });
                //cache list items object
                var $newLi = $newUl.find('ul li');
            }
            //get heights of new elements for use later
            var newUlHeight = Math.max($newUl.height() + opts.marginFix, 0), // JMP - Adjust for negative/positive margins.
                containerHeight = $containerDiv.height(),
                newLiLength = $newLi.length;
            //check if a value is selected
            if (currentIndex != -1) {
                navigateList(currentIndex, true);
            } else {
                //set placeholder text
                $containerDivText.text(opts.defaultText);
            }
            // allows for flexible width of option list
            function setWidth() {
                var fullWidth = null;
                $containerDiv.find('ul li').each(function() {
                    var $this = $(this);
                    $this.css({ position: "absolute", visibility: "hidden", display: "block" });
                    fullWidth = ($this.width() > fullWidth) ? $this.width() : fullWidth;
                    $this.css({ position: "", visibility: "", display: "" });
                });
                if (fullWidth != null) {
                    if (fullWidth < opts.ddMinWidth) fullWidth = opts.ddMinWidth;
                    if (fullWidth > opts.ddMaxWidth) fullWidth = opts.ddMaxWidth;
                    $containerDiv.width(fullWidth)
                    $containerDiv.children('ul').width(fullWidth + opts.ulWidthOffset)
                }
            }
            // set width of option list
            setWidth();
            //decide if to place the new list above or below the drop-down
            function newUlPos() {
                var containerPosY = $containerDiv.offset().top,
                    docHeight = jQuery(window).height(),
                    sTxt = $containerDiv.find('.selectedTxt'),
                    sTxtHeight = sTxt.height() + parseInt(sTxt.css('padding-top')) + parseInt(sTxt.css('padding-bottom')),
                    scrollTop = jQuery(window).scrollTop();
                //if height of list is greater then max height, set list height to max height value
                if (newUlHeight > parseInt(opts.ddMaxHeight)) {
                    newUlHeight = parseInt(opts.ddMaxHeight);
                }
                containerPosY = containerPosY - scrollTop;
                if (containerPosY + newUlHeight + sTxtHeight >= docHeight) {
                    $newUl.css({ top: '-' + (newUlHeight + opts.marginFix) + 'px', height: newUlHeight });
                    $input.onTop = true;
                } else {
                    $newUl.css({ top: 'auto', height: newUlHeight });
                    $input.onTop = false;
                }
            }
            //run function on page load
            newUlPos();
            //run function on browser window resize
            $(window).resize(function() {
                newUlPos();
            });
            $(window).scroll(function() {
                newUlPos();
            });
            //positioning
            function positionFix() {
                $containerDiv.css('position', 'relative');
            }
            function positionHideFix() {
                $containerDiv.css('position', 'static');
            }
            $containerDiv.click(function() {
                if ($newUl.is(':visible')) {
                    $newUl.hide();
                    positionHideFix()
                    return false;
                }
                $containerDiv.focus();
                //show list
                $newUl.slideDown(opts.animationSpeed);
                positionFix();
                //scroll list to selected
                $newUl.scrollTop($input.liOffsetTop);
            });
            $newLi.hover(
              function(e) {
                  var $hoveredLi = $(e.target);
                  $hoveredLi.addClass('newListHover');
              },
              function(e) {
                  var $hoveredLi = $(e.target);
                  $hoveredLi.removeClass('newListHover');
              }
            );
            $newLi.click(function(e) {
                var $clickedLi = $(e.target);
                //update counter
                currentIndex = $newLi.index($clickedLi);
                //remove all hilites, then add hilite to selected item
                prevented = true;
                navigateList(currentIndex);
                //$newUl.hide();
                $containerDiv.css('position', 'static'); //ie
            });
            function navigateList(currentIndex, init) {
                //get offsets
                var containerOffsetTop = $containerDiv.offset().top,
                liOffsetTop = $newLi.eq(currentIndex).offset().top,
                liHeight = $newLi.eq(currentIndex).height(),
                ulScrollTop = $newUl.scrollTop(),
                ulOffsetTop = $newUl.offset().top,
                ulHeight = $newUl.height();
                var debug = 'ulHeight:' + ulHeight + ' (liOffsetTop:' + liOffsetTop + ' - containerOffsetTop:' + containerOffsetTop + ') + ulScrollTop:' + ulScrollTop + ' - (ddMaxHeight/2:' + opts.ddMaxHeight / 2 + ')'
                //get distance of current li from top of list                
                if ($input.onTop == true) {
                    //if list is above select box, add max height value
                    $input.liOffsetTop = ((liOffsetTop - containerOffsetTop) + ulScrollTop - (opts.ddMaxHeight / 2)) + parseInt(opts.ddMaxHeight);
                } else {
                    $input.liOffsetTop = ((liOffsetTop - containerOffsetTop) + ulScrollTop - (opts.ddMaxHeight / 2));
                    
                    $input.liOffsetTop += (ulOffsetTop == containerOffsetTop && currentIndex) ? ulOffsetTop : 0;
                }

                $('#debug').text(debug + ' = ' + $input.liOffsetTop)
                //scroll list to focus on current item
                $newUl.scrollTop($input.liOffsetTop);
                $newLi.removeClass('hiLite')
                    .eq(currentIndex)
                    .addClass('hiLite');
                var text = $newLi.eq(currentIndex).text();
                //page load
                if (init == true) {
                    $input.val(text);
                    $containerDivText.text(text);
                    return false;
                }
                $input.val(text).change();
                $containerDivText.text(text);

            };
            $input.change(function(event) {
                $targetInput = $(event.target);
                //stop change function from firing 
                if (prevented == true) {
                    prevented = false;
                    return false;
                }
                $currentOpt = $targetInput.find(':selected');
                currentIndex = $targetInput.find('option').index($currentOpt);
                navigateList(currentIndex, true);
            }
            );
            //handle up and down keys
            function keyPress(element) {
                //when keys are pressed
                element.onkeydown = function(e) {
                    if (e == null) { //ie
                        var keycode = event.keyCode;
                    } else { //everything else
                        var keycode = e.which;
                    }
                    //prevent change function from firing
                    prevented = true;
                    switch (keycode) {
                        case 40: //down
                        case 39: //right
                            incrementList();
                            return false;
                            break;
                        case 38: //up
                        case 37: //left
                            decrementList();
                            return false;
                            break;
                        case 33: //page up
                        case 36: //home
                            gotoFirst();
                            return false;
                            break;
                        case 34: //page down
                        case 35: //end
                            gotoLast();
                            return false;
                            break;
                        case 13:
                        case 27:
                            $newUl.hide();
                            positionHideFix();
                            return false;
                            break;
                    }
                    //check for keyboard shortcuts
                    keyPressed = String.fromCharCode(keycode).toLowerCase();
                    var currentKeyIndex = keys.indexOf(keyPressed);
                    if (typeof currentKeyIndex != 'undefined') { //if key code found in array
                        ++currentIndex;
                        currentIndex = keys.indexOf(keyPressed, currentIndex); //search array from current index
                        if (currentIndex == -1 || currentIndex == null || prevKey != keyPressed) currentIndex = keys.indexOf(keyPressed); //if no entry was found or new key pressed search from start of array
                        navigateList(currentIndex);
                        //store last key pressed
                        prevKey = keyPressed;
                        return false;
                    }
                }
            }
            function incrementList() {
                if (currentIndex < (newLiLength - 1)) {
                    ++currentIndex;
                    navigateList(currentIndex);
                }
            }
            function decrementList() {
                if (currentIndex > 0) {
                    --currentIndex;
                    navigateList(currentIndex);
                }
            }
            function gotoFirst() {
                currentIndex = 0;
                navigateList(currentIndex);
            }
            function gotoLast() {
                currentIndex = newLiLength - 1;
                navigateList(currentIndex);
            }
            $containerDiv.click(function() {
                keyPress(this);
            });
            $containerDiv.focus(function() {
                $(this).addClass('newListSelFocus');
                keyPress(this);
            });
            //hide list on blur
            $containerDiv.blur(function() {
                $(this).removeClass('newListSelFocus');
                $newUl.hide();
                positionHideFix();
            });
            //add classes on hover
            $containerDivText.hover(function(e) {
                var $hoveredTxt = $(e.target);
                $hoveredTxt.parent().addClass('newListSelHover');
            },
              function(e) {
                  var $hoveredTxt = $(e.target);
                  $hoveredTxt.parent().removeClass('newListSelHover');
              }
            );
            //reset left property and hide
            $newUl.css('left', '0').hide();
        });
    };
})(jQuery);
/* End Stylish Select Plugin
*********************************************************************************************/
