/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Site Specific Functions (Responsive)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

youthranch = (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 layout.scss match the variables (no units):
                $tablet_breakpoint and $desktop_breakpoint
             */
            'tablet'  : 480,
            'desktop' : 768
        },
        device;

/* Set default values of Ajax requests */
    $.ajaxSetup({ cache: true });

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

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

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.mobileSideNav = function () {
    /* adds/removes class to html on mobile to trigger mobile nave styles.
       also moves subnav to appropriate parent li (if it's elsewhere in DOM)
       also makes mobile nave "sticky"
       DEPENDENCIES: fn.getDevice
                     fn.moveSubnav
                     fn.stickyObject
     */
        var makeMobile  = function () {
                if (device != 'mobile') {
                    //tablet/desktop 
                    $('html').removeClass('js-ready');
                    fn.moveSubnav();
                };
                if (device == 'mobile') {
                    //mobile
                    $('html').addClass('js-ready');
                    fn.moveSubnav();
                };
            };

        makeMobile();

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

        $('a.mobile-navigation').on('click', function (e) {
            e.preventDefault();
            $('html').toggleClass('js-nav');
            $(this).toggleClass('open closed');
            $('a.mobile-navigation.closed').attr('href', '#top');
            $('a.mobile-navigation.open').attr('href', '#navigation');
        });

    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.moveSubnav = function () {
        var subNav  = $('ul.second-level'),
            mainNav = $('#navigation ul'),
            current = mainNav.find('li.current');
        if ($('#navigation').children('ul.second-level').length == 0 && device != 'mobile') {
            for (var i = 0; i < subNav.length; i++) {
                subNav.eq(i).insertAfter('nav.subnav h4:eq(' + i + ')');
            }
        }
        if (current.children('ul.second-level').length == 0  && device == 'mobile') {
            subNav.appendTo(current);
        }
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    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.sameHeight = function (selector, viewport) {
    //hat tip: https://css-tricks.com/equal-height-blocks-in-rows/
        var items           = $(selector),
            currentTallest  = 0,
            currentRowStart = 0,
            topPosition     = 0,
            rowDivs         = new Array(),
            functionClass   = 'fn_sameHeight',
            views           = ($.isArray(viewport)) ? viewport.join() : ((viewport === undefined) ? 'mobile, tablet, desktop' : viewport),
            doIt = function () {
                if (views.indexOf(device) > -1) {
                    items.each( function () {
                        var el = $(this);
                        el.addClass(functionClass);
                        topPosition = el.position().top;
                        if (currentRowStart != topPosition) {

                            for (var currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) {
                                rowDivs[currentDiv].height(currentTallest);
                            }

                        // set the variables for the new row
                            rowDivs.length = 0; // empty the array
                            currentRowStart = topPosition;
                            currentTallest = el.height();
                            rowDivs.push(el);

                        } else {

                        // another div on the current row.  Add it to the list and check if it's taller
                            rowDivs.push(el);
                            currentTallest = (currentTallest < el.height()) ? (el.height()) : (currentTallest);

                        }

                        // do the last row
                        for (var currentDiv = 0 ; currentDiv < rowDivs.length ; currentDiv++) {
                            rowDivs[currentDiv].height(currentTallest);
                        }
                    });
                } else {
                    items.each( function () {
                        $(this).removeClass(functionClass).height('');
                    })
                }
            };
        doIt();
        $(window).resize(doIt);
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.stickyObject = function (selector) {
        var stickyThang = $(selector),
            stickyStart = stickyThang.offset().top,
            stickyStop  = $('footer[role="contentinfo"]').offset().top;

        if (stickyThang) {

            $(window).on('scroll', function () {
                var windowScroll = $(window).scrollTop();
                var offset = windowScroll - 43;

                if (windowScroll >= stickyStart) {
                    stickyThang.addClass('stuck').css({
                        'top' : offset + 'px',
                        'z-index' : 9000
                    });
                } else {
                    stickyThang.removeClass('stuck').removeAttr('style');
                };

            });
        };
    };
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadTablesorter = function (selector) {
        var script = jsFolder + 'tablesorter.js',
            table  = $(selector);
        $.getScript(script)
          .done(function () {
              table.tablesorter();
          })
          .fail(function () {
              if (window.console) {
                  console.log(script + ' failed to load.')
              }
          });
    };
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    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 = debounce(function () {
                responsiveImage.each(function () {
                    var image = $(this),
                    src  = image.data(device);
                    $(this).attr('src', src);
                });
            }, 250);
        getImage();
        $(window).resize(function () {
            getImage();
        });
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.showMoreInfo = function (q,a,context,remove) {
      //call like this:
      //siteName.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
            .parents(context).addClass('fn_showMoreInfo').find(a).addClass('drawer').hide();

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

            e.preventDefault();

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

                if (remove || remove === true) {
                    trigger.slideUp();
                }

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

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

            };

        });

    }
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.showHideOther = function (form, trigger, other, deselector, positiveValue) {
      var ctx        = $(form),
          trigger    = $(trigger, ctx),
          otherField = $(other, ctx),
          deselector = $(deselector, ctx)
          positiveValue = (positiveValue) ? positiveValue : 'Yes';

      otherField.parents('div.group').hide().addClass('specify');
      trigger.each(function () {
        var group = otherField.parents('div.group');
        $(this).on('change', function (){
            if ($(this).val() != '' && positiveValue.indexOf($(this).val()) > -1 ) {
              group.slideDown();
              return;
            };
            if ($(this).is(':checked') || $(this).is(':selected')) {
              group.slideDown();
              return;
            };
            if ($(this).not(':checked') || $(this).not(':selected') || $(this).val() == '') {
              group.slideUp();
              otherField.val('');
              return;
            }
            if (positiveValue.indexOf($(this).val()) < 0) {
              group.slideUp();
              otherField.val('');
            }
        });
      });

      deselector.each(function () {
        var group = otherField.parents('div.group');
        $(this).on('change', function (){
          if ($(this).is(':checked') || $(this).is(':selected')) {
            group.slideUp();
            otherField.val('');
          }
        });
      })

    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    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.formFocus = function (selector) {
    /* adds a tagetable class to filled and focused input fields */
        var ctx = $(selector),
            fields = $('input:not([type="submit"], [type="reset"]), textarea', ctx),
            functionClass = 'fn_formFocus-filled';
        fields.each(function() {
            if ($(this).val() != '') {
                $(this).parents('.group').addClass(functionClass)
            }
        }).on({
            blur : function () {
                if ($(this).val() == '' || ($(this).attr('placeholder') == '' && $(this).val() == '')) {
                    $(this).parents('.group').removeClass(functionClass);
                }
            },
            focus : function () {
                $(this).parents('.group').addClass(functionClass);
            }
        })
    }

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    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.loadValidator = function (selector) {
        // Source for files: https://github.com/posabsolute/jQuery-Validation-Engine
        var scripts = [
                'jquery.validationEngine.js',
                'jquery.validationEngine-en.js'
            ],
            count   = 0,
            goScripts,
            target  = $(selector);

        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 () {
            $(target).validationEngine();
        }
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadFancyBox = function (selector, options) {
        var scripts = [
                      'jquery.fancybox.pack.js',
                      'jquery.fancybox-media.js'
                    ],
            count   = 0,
            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,
            doIt   = function () {
                        options.preload = true;
                        options.helpers = {
                            media : {
                                youtube : {
                                    params : {
                                        autoplay : 0
                                    }
                                }
                            }
                        };
                        selector.fancybox(options);
            };
        $.ajaxSetup({ cache: true });
        for (var i = 0; i < scripts.length; i++) {
            var url = jsFolder + scripts[i];
            $.getScript(url)
                .done(function () {
                    count++;
                    if (window.console) {
                        console.log(url + ' loaded successfully!');
                    };
                    if (count == scripts.length) {
                        doIt();
                    }
                })
                .fail(function () {
                  if (window.console) {
                    console.log(url + ' failed to load.');
                  };
                });
          }
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    fn.loadCycle = function (selector, progress) {
        var scriptURL = jsFolder + 'jquery.cycle2.min.js',
            selector  = $(selector),
            progress  = $(progress),
            options   = {
                    //defaults listed here: http://jquery.malsup.com/cycle2/api/#options
                                                log : true,
                                             slides : '> div.slide',
                                           // paused : true,
                                       pauseOnHover : true,
                                              speed : 600
                                   //            pager : '> div.pager',
                                   //    pagerTemplate : '<span>&emsp;</span>',
                                   // pagerActiveClass : 'current'
                };
        if (selector.is(':visible')) {
            $.getScript(scriptURL)
                .done(function () {
                    // can override or add options here with the syntax options.OPTION_NAME = 'new value'
                    selector.cycle(options);
                    selector.on( 'cycle-initialized cycle-before', function( e, opts ) {
                        progress.stop(true).css( 'width', 0 );
                    });

                    selector.on( 'cycle-initialized cycle-after', function( e, opts ) {
                        if ( ! selector.is('.cycle-paused') ) {
                            progress.animate({ width: '100%' }, opts.timeout, 'linear' );
                        }
                    });

                    selector.on( 'cycle-paused', function( e, opts ) {
                       progress.stop(); 
                    });

                    selector.on( 'cycle-resumed', function( e, opts, timeoutRemaining ) {
                        progress.animate({ width: '100%' }, timeoutRemaining, 'linear' );
                    });
                })
                .fail(function () {
                    if (window.console) {
                        console.log(scriptURL + ' didn\'t load');
                    }
                });
        };
    };

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    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);
                   selector.on('change', function () {
                       var url = $(selector).find('option:selected').val();
                       if (url != '') {
                           window.location = $(selector).find('option:selected').val();
                       }
                   });
                 })
                 .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';
                    youthranch.testFunction();
                });
            </script>
        -----------------------------*/
        getDevice          : fn.getDevice,
        stickyObject       : fn.stickyObject,
        sameHeight         : fn.sameHeight,
        showMoreInfo       : fn.showMoreInfo,
        loadValidator      : fn.loadValidator,
        loadFancyBox       : fn.loadFancyBox,
        loadCycle          : fn.loadCycle,
        loadChosen         : fn.loadChosen,
        formFocus          : fn.formFocus,
        formatPhoneNumbers : fn.formatPhoneNumbers,
        showHideOther      : fn.showHideOther,
        loadTablesorter    : fn.loadTablesorter,

        init : function () {
            /*-----------------------------*
                these always run
            -----------------------------*/
            fn.initializeVars();
            fn.getDevice();
            fn.mobileSideNav();
            fn.responsiveImageSize();
            fn.smoothScroll();
        }
    }
})(jQuery);

/*-----------------------------------*
  When DOM is loaded, call the functions in "init" section
  -----------------------------------*/
$(document).ready(function(){
    'use strict';
    var device;
    youthranch.init();
    device = youthranch.getDevice();
    $('a.sign-up, a.charity-navigator').off('click.smooth');
    youthranch.loadFancyBox('a.sign-up', {
        width    : (device == 'mobile') ?  '200' : '500',
        maxWidth : '500',
        title    : null,
        wrapCSS  : 'mayalcahimp'
    });
});
