/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Sitewide and Public Functions (Responsive)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

ncmedboard = (function ($) {
    'use strict';

    var E  = {}, /* set an object to streamline all DOM elements */
        fn = {}, /* set an object to streamline all functions */
        jsFolder = '/themes/javascript/compressed/jquery/plugins/', /* The path to the JS folder */
        size = {
            /* in base.scss we can calculate
               ( $column-width + $gutter-width ) * $tablet ) - $gutter-width */
            'mobile'  : 480,
            'tablet'  : 715,
            'desktop' : 955
        },
        device;

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
// Set up contextual regions for quicker selection/searching later   
    fn.initializeVars = function () {
        E.header      = $('header[role="banner"]');
        E.mainNav     = $('nav.main');
        E.subNav      = $('nav.subnav');
        E.mainContent = $('main[role="main"]');
        E.footer      = $('footer[role="contentinfo"]');
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 
/* get device based on responsive size
   you can test against "device" variable in any function
   DEPENDENCIES - global vars "size" and "device"
 */
    fn.getDevice = function () {
        var runCheck = function () {
              if ( ($(window).width() >= size.mobile && $(window).width() <= size.tablet) || $(window).width() < size.mobile) {
                  device = 'mobile';
              }
              if ( $(window).width()  > size.tablet && $(window).width() <= size.desktop ) {
                  device = 'tablet';
              }
              if ( $(window).width() >= size.desktop ) {
                  device = 'desktop';
              }
            };
        runCheck();
        $(window).resize( function () {
            runCheck();
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// A test function to show load success and give color swatches if you want
  fn.testFunction = function () {
      if (window.console) {
          console.log('Nailed it! The custom javascript is loaded!');
          console.log('You can remove "fn.testFunction()" from line 115 of the custom js file.');
          console.log('Then you can call it whenever you want by following the example on lines 100-107.');
          console.log('To see the base swatches add \"<div class=\"color-test\"></div>\" to your page.');
      }
      if ($('div.color-test').length) {
        if (window.console) {
          console.log('Oh! I see you\'ve done that! Nice work!');
        }
        var ctx = $('div.color-test'),
            S   = [
                    '<p>Swatch One (.swatch-one)</p>',
                    '<div class="swatch-one',
                    '">&nbsp</div>',
                    '<p>Swatch Two (.swatch-two)</p>',
                    '<div class="swatch-two'
                  ],
            content = [];
        content.push(S[0] + S[1] + S[2]);
        for (var i = 1; i < 10; i++) {
          content.push(S[1] + '-' + i + S[2])
        };
        content.push(S[3] + S[4] + S[2]);
        for (var i = 1; i < 10; i++) {
          content.push(S[4] + '-' + i + S[2])
        };
        ctx.append(content);
      };
      if (window.console) {
        console.log('Remove these console.logs or the whole testFunction when satisfied.')
      }
  };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.mobileSideNav = function () {
      var body        = $('body'),
          openButton  = $('a.open-navigation'),
          closeButton = $('a.close-navigation'),
        makeMobile  = function () {
            if (device == 'tablet' || device == 'desktop') {
              //tablet/desktop 
              $('html').removeClass('js-ready');
              if ($('div.wrapper', E.mainNav).length == 0) {
                E.mainNav.wrapInner('<div class="wrapper"></div>');
              };
              $('div.mobile-wrapper, div.mobile-wrapper > *').unwrap();
            };
            if (device == 'mobile') {
              //mobile
              $('html').addClass('js-ready');
              $('div.wrapper > ul', E.mainNav).unwrap();
              if ($('div.mobile-outer-wrapper').length == 0) {
                body.wrapInner('<div class="mobile-outer-wrapper"><div class="mobile-wrapper">');
              };
            };
          };

      makeMobile();

      $(window).resize(function() {
          makeMobile();
      })

      openButton.add(closeButton).on('click', function (e) {
          e.preventDefault();
          $('html').toggleClass('js-nav');
      });

    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.siteSearchBar = function () {
// in tablet and desktop view, clicking magnifying glass in main nav reveals search form
// in mobile, magnifying glass (now in sidenav) links to search page
// change the position in DOM because of fullwidth display style.
        var magnifyingGlass = $('li.search a[title*="Search"]', E.mainNav),
            searchBox       = $('form.search-box').not('.static'),
            doIt            = function () {
                magnifyingGlass.off('click');
                if (device == 'mobile') {
                    searchBox.insertAfter(E.mainNav).show();
                    magnifyingGlass.on('click', function (e) {
                        e.preventDefault();
                        if (device == 'mobile') {window.location = $(this).attr('href')}
                    });
                } else {
                    searchBox.appendTo(E.mainNav).hide();
                    magnifyingGlass.on('click', function (e) {
                        e.preventDefault();
                        $(this).parent('li').toggleClass('current');
                        searchBox.slideToggle(300)
                            .toggleClass('open')
                            .find('input[type="text"]')
                                .focus();
                    });
                }
                $(window).resize(function () {
                    doIt();
                });
            };
        doIt();
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.responsiveImageSize = function () {
    /* Load appropriately sized images from data-mobile|data-tablet|data-desktop attributes.
        Triggered by class="responsive" on <img>.
        <img
        class="responsive"
        alt="XXXXXXX"
        src="[path to mobile - for best result, use mobile as default]"
        data-mobile ="[path to mobile]"
        data-tablet ="[path to tablet]"
        data-desktop="[path to desktop]">
        DEPENDECIES - fn.getDevice();
     */
        var responsiveImage = $('img.responsive'),
            getImage = function () {
                responsiveImage.each(function () {
                    var image = $(this),
                        src  = image.data(device);
                    $(this).attr('src', src);
                });
            };
        getImage();
        $(window).resize(function () {
            getImage();
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadCycle = function () {
        var scriptURL = jsFolder + 'jquery.cycle2.min.js',
            loadPagerData;
        if ($('.slideshow:visible')) {
            $.ajaxSetup({ cache: true });
            $.getScript(scriptURL)
                .done(function () {
                    $('.slideshow').cycle({
                                     log : false,
                                  slides : '> div.slide',
                                      fx : 'fade',
                               // paused : true,
                                   speed : 600,
                                   pager : '> div.pager',
                           pagerTemplate : '<span data-slide-number="{{slideNum}}">&emsp;</span>',
                        pagerActiveClass : 'current'
                    })
                    .on('cycle-after', function () {
                        if (device == 'mobile') {
                            //resize mobile slideshow div so we overlap content
                            var slide       = $('.js-ready .cycle-slide-active'),
                                slideHeight = $('.js-ready .cycle-slide-active').height(),
                                infoHeight  = $('.js-ready .cycle-slide-active .slide-info').height();
                            $(this).animate({'height': slideHeight}, 500);
                        }
                    });
                    $('.slide.has-link').on('click', function () {
                        var href = $(this).find('a.read-more, .slide-image a').attr('href');
                        if (href != null) {
                            window.location = href;
                        }
                    });
                    
                    $(window).resize(function () {
                        $('.slideshow').removeAttr('style');
                    });
                    loadPagerData = function () {
                        var pager = $('div.pager span');
                        pager.each(function () {
                            var number = $(this).data('slide-number'),
                                title = $('div.slide[data-slide-number="' + number + '"] div.slide-image img').attr('alt').trim();
                                $(this).attr('title', title);
                        })
                    };
                    loadPagerData();
                })
                .fail(function () {
                    if (window.console) {
                        console.log(scriptURL + ' didn\'t load');
                    }
                });
        };
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadFancyBox = function (selector, options) {
        var scriptURL = jsFolder + 'jquery.fancybox.pack.js',
            selector = $(selector),
            options  = (!options || options == '') ? {
                    //defaults listed here: http://fancyapps.com/fancybox/
                    padding : 15,
                    marging : 20,
                    width: 800,
                    height: 600,
                    minWidth: 100,
                    minHeight: 100,
                    maxWidth: 9999,
                    maxHeight: 9999,
                    autoSize: true,
                    autoHeight: false,
                    autoWidth: false
                    // there's a crap-ton more at the url above -- these are defaults shown as a guide for what can be overridden with
                    // options.padding == [42,12,42,12]
                } : options;
        $.ajaxSetup({ cache: true });
        $.getScript(scriptURL)
            .done(function () {
                selector.fancybox(options);
            })
            .fail(function () {
                if (window.console) {
                    console.log(scriptURL + ' didn\'t load');
                }
            });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.sizeSideNav = function () {
        var newHeight,
            doIt = function () {
                if (device != 'mobile') {
                    $('nav.subnav').css('height',newHeight);
                }
            };
        $(document).ready(function(){
            newHeight = $('main[role="main"]').outerHeight()
            doIt();
        })
        $(window).resize(function() {
            newHeight = $('main[role="main"]').outerHeight()
            doIt();
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.showMoreInfo = function (q,a,context,remove) {
      //call like this:
      //ncmedboard.showMoreInfo('.q-selector', '.a-selector', '.context-selector, [true|false]);
      //q == what you click
      //a == what gets revealed
      //context == parent/container
      //remove == BOOLEAN remove q?
      //DEPENDENCY: fn.hideMoreInfo

        var clickMe         = $(q),
            closeButtonHTML = '<i class="fa fa-close"></i>&ensp;Close';

        clickMe
            .next(a).addClass('drawer').hide().end()
            .parents(context).addClass('fn_showMoreInfo');

        clickMe
            .off('click.smooth')
            .on('click.showMore', function (e) {
            var ctx     = $(this).parents(context),
                trigger = $(this),
                pos     = ctx.offset().top,
                drawer  = $(this).next(a, ctx);

            e.preventDefault();

            if (!ctx.hasClass('open')) {

                if (remove) {
                    trigger.slideUp();
                }

                drawer.slideDown(function () {
                    if (device != 'mobile') {
                        $('nav.subnav').css('height', $('main[role="main"]').outerHeight());
                    }
                });

                if (!remove) {
                    drawer.append('<a class="close">' + closeButtonHTML + '</a>');
                    trigger.slideUp(100);
                    ctx.addClass('open');
                    drawer.find('a.close').on('click.hideMore', function () {
                        fn.hideMoreInfo($(this),q,a,pos);
                    })
                }

            };

        });

    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.hideMoreInfo = function (elem,q,a,pos) {
        var ctx     = elem.parents('.fn_showMoreInfo.open'),
            trigger = elem,
            drawer  = $(a, ctx),
            origTrigger = $(q, ctx),
            origPosition = pos;
        drawer.slideUp(1000);
        ctx.removeClass('open');
        trigger.remove();
        origTrigger.slideDown(100);
        $('body').animate({scrollTop:origPosition}, 1000, function () {
            if (device != 'mobile') {
                $('nav.subnav').css('height', $('#main-content').outerHeight());
                if (parseInt($('#main-content').outerHeight()) > parseInt($('nav.subnav').innerHeight())) {
                    $('nav.subnav').css('height', 'auto');
                }
            }
        });
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.smoothScroll = function () {
        $('a[href^=#]').on('click.smooth', function(e) {

            e.preventDefault();

            if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') || location.hostname == this.hostname) {

                var target = $(this.hash);

                target = target.length ? target : $('[name=' + this.hash.slice(1) +'], [id=' + this.hash.slice(1) +']');

                if (target.length) {
                    $('html,body').animate({
                        scrollTop: target.offset().top
                    }, 1000);

                    $('.target').removeClass('target');

                }

                target.addClass('target');

            }
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.tabbedSections = function (tabs, sections) {
// USAGE: set up HTML something like this
// <nav class="tabs">
//   <ul>
//     <li><a href="#XXX" title="XXX" >XXX</a></li>
//     <li><a href="#YYY" title="YYY" >YYY</a></li>
//     <li><a href="#ZZZ" title="ZZZ" >ZZZ</a></li>
//   </ul>
// </nav>
// <section class="tabs_section" id="XXX">...</section>
// <section class="tabs_section" id="YYY">...</section>
// <section class="tabs_section" id="ZZZ">...</section>
//
// Then callthe JS with siteName.tabbedSections('.tabs', '.tab_section')

        var tabs          = $(tabs),
            links         = $('a', tabs),
            sections      = $(sections),
            urlHash       = window.location.hash,
            activeOnLoad  = ($(urlHash).length > 0) ? $(urlHash).eq(0) : false,
            functionClass = 'fn_tabbedSections',
            tabsClass     = functionClass + '-tabs',
            sectionClass  = functionClass + '-section',
            currentClass  = functionClass + '-current';

        // add classes for styling
        tabs.add(sections).parent().addClass(functionClass);
        tabs.addClass(tabsClass);
        sections.addClass(sectionClass);

        // when script loads
        if (!activeOnLoad) {
        // if there isn't a targeted ID in url, hide all but first section
            sections.not(':eq(0)').hide();
            $('li', tabs).eq(0).add(sections.eq(0)).addClass(currentClass);
        } else {
        // if there is a targeted ID in url, show that one
            sections.hide();
            $('a[href*=' + urlHash + ']', tabs).parents('li').add(activeOnLoad).show().addClass(currentClass);
            $('body').scrollTop(500);
        }

        if (device != 'mobile') {
            $('nav.subnav').css({
                'min-height' : $('#main-content').outerHeight(),
                'height' : 'auto'
            });
        }

        // for each link
        for (var i = 0; i < links.length; i++) {
            var tab = links.eq(i);
        // on click
            tab
              .off('click.smooth')
              .on('click', function (e) {
                var tab           = $(this).parents('li'),
                    otherTabs     = $('li', tabs).not(tab),
                    id            = $(this).attr('href'),
                    section       = $(id),
                    otherSections = sections.not(id);
        // disable link behavior
                e.preventDefault();
        // show appropriate section
                section.show().addClass(currentClass);
                tab.addClass(currentClass);
        // hide the others
                otherSections.hide().removeClass(currentClass);
                otherTabs.removeClass(currentClass);
        // resize the sidebar
                if (device != 'mobile') {
                    $('nav.subnav').css({
                        'min-height' : $('#main-content').outerHeight(),
                        'height' :'auto'
                    });
                }
            })
        }
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.linkTableRows = function () {
        var ctx    = E.mainContent,
            tables = $('table.link-rows', ctx);
        tables.each(function () {
            var table = $(this),
                row   = $('tbody tr', table);

            row.each(function () {
                var link  = $(this).find('td a').eq(0),
                    url   = link.attr('href'),
                    title = link.attr('title'),
                    cells = $('td', $(this)),
                    css   = {
                        'cursor' : 'pointer'
                    };
                cells
                    .css(css)
                    .attr('title', title)
                    .on('click', function () {
                        window.location = $(this).parent('tr').find('td a').attr('href');
                    });
            });
        });
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.formatPhoneNumbers = function (form, fieldName) {
        var ctx         = $(form),
            phoneFields = $('input[name$="' + fieldName + '"]', ctx);
        phoneFields.each(function () {
            $(this)
                .attr({
                    'placeholder' : '(###) ###-####',
                    'pattern'     : '\\(\\d{3}\\) \\d{3}-\\d{4}'
                })
                .on('blur', function () {
                    var field = $(this),
                        value = $(this).val(),
                        strip = value.replace(/\D/g,''),
                        spltz = strip.split(''),
                        newValue;

                    (spltz[0] == 'undefined') ? 'X' : spltz[0];
                    (spltz[1] == 'undefined') ? 'X' : spltz[1];
                    (spltz[2] == 'undefined') ? 'X' : spltz[2];
                    (spltz[3] == 'undefined') ? 'X' : spltz[3];
                    (spltz[4] == 'undefined') ? 'X' : spltz[4];
                    (spltz[5] == 'undefined') ? 'X' : spltz[5];
                    (spltz[6] == 'undefined') ? 'X' : spltz[6];
                    (spltz[7] == 'undefined') ? 'X' : spltz[7];
                    (spltz[8] == 'undefined') ? 'X' : spltz[8];
                    (spltz[9] == 'undefined') ? 'X' : spltz[9];

                    if (value != '') {
                        newValue = '(' + spltz[0] + spltz[1] + spltz[2] + ') ' + spltz[3] + spltz[4] + spltz[5] + '-' + spltz[6] + spltz[7] + spltz[8] + spltz[9];
                        $(this).val(newValue.replace(/undefined/g,''))
                    };
                });
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.validator = function (selector, options) {
        // Source for files: https://github.com/posabsolute/jQuery-Validation-Engine
        // USAGE: pass selector as string and plugin options as {key: value} like:
        //        siteName.validation('form.validator', {promptPosition : "centerRight", scroll: false});
        var scripts = [
                       'jquery.validationEngine.js',
                       'jquery.validationEngine-en.js'
                     ],
            count   = 0,
            goScripts;
        
        for (var i = 0; i < scripts.length; i++) {
            var url = jsFolder + scripts[i];
            $.getScript(url)
                .done(function () {
                    count++;
                    if (count == scripts.length) {
                        goScripts();
                    }
                })
                .fail(function () {
                    if (window.console) {
                        console.log(url + ' failed to load.');
                    };
                });
        }
        
        goScripts = function () {
            $(selector).validationEngine(options);
        };
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.transformFieldToDiv = function (form, field, group) {
        var ctx              = $(form),
            field            = $(field, ctx),
            group            = field.parents(group),
            functionClass    = 'fn_transformFieldToDiv',
            targetClass      = functionClass + '-target',
            transformedClass = functionClass + '-transformed',
            targetValue;
        group
            .addClass(functionClass)
            .append('<div class="' + transformedClass + '">');
        field
            .addClass(targetClass)
            .clone()
            .appendTo('.' + transformedClass);
        field.hide();
        targetValue = $('.' + targetClass).val();
        $('.' + transformedClass).find('.' + targetClass).replaceWith(targetValue)
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.characterCount = function (form, field, group, limit) {
        var ctx           = $(form),
            field         = $(field, ctx),
            group         = field.parents(group),
            label         = field.siblings('label[for$=' + field.attr('name') + ']', ctx),
            limit         = new Number(limit),
            functionClass = 'fn_characterCount',
            wrapperClass  = functionClass + '-wrapper',
            countClass    = functionClass + '-count',
            limitClass    = functionClass + '-limit',
            underClass    = functionClass + '-under',
            overClass     = functionClass + '-over',
            equalClass    = functionClass + '-equal',
            countSpan,
            S = [
                '<span class="',
                '">',
                '</span>',
                ' / '
            ];
// add elements to DOM
        group
            .addClass(functionClass)
            .append(S[0] + wrapperClass + S[1] + S[0] + countClass + S[1] + S[2] + S[3] + S[0] + limitClass + S[1] + parseInt(limit) + S[2] + S[2]);

            countSpan = group.find('.' + countClass);

// test for initial value
        if (field.val().length > 0) {
            countSpan.text(field.val().length);
        } else {
            countSpan.text('0');
        }

        field
            .attr('maxlength', limit)
            .on('keyup blur focus change', function() {
                var theField = $(this),
                    value = theField.val(),
                    count = theField.val().length;
                if (count > limit) {
                    var stopTxt = theField.val().substring(0, limit);
                    countSpan
                        .removeClass(                  underClass + ' ' + equalClass)
                        .addClass(   overClass)
                        .text(stopTxt.length);
                    theField.val(stopTxt);
                }
                if (count < limit) {
                    countSpan
                        .removeClass(overClass + ' ' +                    equalClass)
                        .addClass(                     underClass)
                        .text(count);
                }
                if (count == limit) {
                    countSpan
                        .removeClass(overClass + ' ' + underClass)
                        .addClass(                                        equalClass)
                        .text(count);
                }
            });

    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.otherOptionValue = function (form, otherSelect, otherText) {
        var ctx       = $(form),
            field     = $(otherSelect, ctx),
            textField = $(otherText, ctx);
        textField.on('keyup blur focus change', function () {
            field.val($(this).val());
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadChosen = function (selector, options) {
        var scriptURL = jsFolder + 'chosen.jquery.min.js',
            selector  = $(selector),
            options   = (!options || options == '') ? {
                    //defaults listed here: http://harvesthq.github.io/chosen/options.html
                              allow_single_deselect : false,
                                     disable_search : false,
                           disable_search_threshold : 0,
                           enable_split_word_search : true,
                             inherit_select_classes : false,
                               max_selected_options : Infinity,
                                    no_results_text : 'No results match',
                          placeholder_text_multiple : 'Select Some Options',
                            placeholder_text_single : 'Select an Option',
                                    search_contains : false, // By default, Chosen’s search matches starting at the beginning of a word. Setting this option to true allows matches starting from anywhere within a word. This is especially useful for options that include a lot of special characters or phrases in ()s and []s.
                           single_backstroke_delete : true,
                                              width : selector.parents('form').width() + 'px', // The width of the Chosen select box. By default, Chosen attempts to match the width of the select box you are replacing. If your select is hidden when Chosen is instantiated, you must specify a width or the select will show up with a width of 0.
                           display_disabled_options : true,
                           display_selected_options : true,
                    include_group_label_in_selected : false
                } : options;
        if (selector.is(':visible')) {
             $.getScript(scriptURL)
                 .done(function () {
                   selector.chosen(options);
                 })
                 .fail(function () {
                     if (window.console) {
                         console.log(scriptURL + ' didn\'t load');
                     }
                 });
        };
    };

    return {
        /*-----------------------------*
          set Public APIs that can be
          called on any page using
          <script type="text/javascript">
            $(document).ready(function(){
              'use strict';
              ncmedboard.testFunction();
            });
          </script>
          -----------------------------*/
        testFunction        : fn.testFunction,
        loadCycle           : fn.loadCycle,
        validator           : fn.validator,
        showMoreInfo        : fn.showMoreInfo,
        tabbedSections      : fn.tabbedSections,
        linkTableRows       : fn.linkTableRows,
        loadFancyBox        : fn.loadFancyBox,
        formatPhoneNumbers  : fn.formatPhoneNumbers,
        transformFieldToDiv : fn.transformFieldToDiv,
        characterCount      : fn.characterCount,
        loadChosen          : fn.loadChosen,
        otherOptionValue    : fn.otherOptionValue,
  
        init : function () {
        /*-----------------------------*
          these always run
          -----------------------------*/
            fn.initializeVars();
            fn.getDevice();
            fn.mobileSideNav();
            fn.siteSearchBar();
            fn.responsiveImageSize();
            fn.sizeSideNav();
            fn.smoothScroll();

        }
    }
})(jQuery);

/*-----------------------------------*
  When DOM is loaded, call the functions in "init" section
  -----------------------------------*/
$(document).ready(function(){
  'use strict';
  ncmedboard.init();
});
