EDJ.run_list = [
    'external_link',
    'navigation',
    'gallery_blocks',
    'chosen',
    'quick_jump',
    'ui_tabs',
    'validation',
    'youtube_modal',
    'more_results_ajax',
    'partners_equal',
    'recruit_add_friend',
    'soae'
];


/**
 * On ready
 *
 * Called when document is ready
 *
 * Used on: all pages
 *
 * @namespace EDJ
 * @param settings
 * @class on_ready
 * ---------------------------------------------------------------------------------------------------
*/
EDJ.on_ready = function(settings) {
    var i = 0;
    var functions_to_run = EDJ.run_list.length;

    // Extend the settings object with any vars passed in
    $.extend(EDJ.settings, settings);

    // Cache the body object for use later
    EDJ.$body = $('body');
    
    // Loop through our functions and run those that exist and said they should
    for (i=0; i<functions_to_run; i++) {
        // If the init function exists, and the run key is set to true
        if (
            (typeof EDJ[EDJ.run_list[i]].run === 'function' && EDJ[EDJ.run_list[i]].run() === true) ||
            (typeof EDJ[EDJ.run_list[i]].run === 'boolean' && EDJ[EDJ.run_list[i]].run === true)
        ) {
            // Log that we've called the init function
            EDJ.log('initialising EDJ.'+EDJ.run_list[i]);

            // Call the init function!
            EDJ[EDJ.run_list[i]].init();

            // Log that we've finished the init function
            EDJ.log('finished running EDJ.'+EDJ.run_list[i]);

        }

    }

};


/**
 * Log
 *
 * Will log any arguments (arrays, objects, strings etc.) to the console
 * if it exists, and EDJ.settings.debug is set to true
 *
 * Used on: all pages
 *
 * @namespace EDJ
 * @class log
 * @param anything!
 * ---------------------------------------------------------------------------------------------------
*/
EDJ.log = function() {
    if (EDJ.settings.debug === true && typeof(console) !== 'undefined') {
        console.log('[EDJ] ' + Array.prototype.join.call(arguments, ' '));
    }
};


/**
 * External Link
 *
 * Opens links in a new window
 */
EDJ.external_link = {
    run: true,

    init: function() {
        var $external_link = $('a[rel="external"]');
        
        $external_link.click(function(e) {
            e.preventDefault();
            window.open($(this).prop('href'), "en-external", "width=640, height=440");
        });

    }

};


/**
 * Navigation
 *
 * Various helpers for naviation
 *
 * Used on: all pages
 *
 * @namespace EDJ
 * @class navigation
 * ---------------------------------------------------------------------------------------------------
*/
EDJ.navigation = {
    run: true,

    init: function() {
        var $access_links = EDJ.$body.find('ul#nav_access li a');

        $access_links.focus(function(){ 
            $(this).addClass('focus');
        });

        $access_links.blur(function(){ 
            $(this).removeClass('focus'); 
        });

    }

};

/**
 * Gallery blocks
 */
EDJ.gallery_blocks = {
    $gallery_blocks: {},
    speed: 300,
    selector: '.block_gallery',
    auto_advance: true,
    time_out: 6000,

    run: function() {
        this.$gallery_blocks = EDJ.$body.find(this.selector);
        return this.$gallery_blocks.length > 0;
    },

    init: function() {
        var $slides = this.$gallery_blocks.find('.slides > div'),
            that = this
            height = 0,
            $first_slide = $slides.filter(':eq(0)');

        // Hide all but the first slide
        $slides.filter(':gt(0)').hide();
        // Get the height of the first slide for when we position absolute it all
        height = $slides.filter(':eq(0)').outerHeight(true);
        // Set the slideshow's height to the first slides
        $first_slide.closest('.slides').height(height);
        // Set all the slides to position absolute so they can gracefully dissolve
        $slides.css({ position: 'absolute', top: 0, left: 0 });

        //Setup auto advance
        if( this.auto_advance )
        {
            var slide_autoadvance= setInterval(function(){
                that.advance(); 
            }, this.time_out);
        }

        // Set the click event for each slide
        this.$gallery_blocks.delegate('.nav li', 'click', function(e) {
            var $slideshow = {},
                $slide = {},
                height = 0;

            e.preventDefault();

            if(e.hasOwnProperty('originalEvent'))
                clearInterval(slide_autoadvance);

            $slideshow = $(this).closest(that.selector).find('.slides');
            // Find this clicked items equivalent in the slide deck
            $slide = $slideshow.find('> div:eq(' + $(this).index()  + ')');

            // If it's already visible, we don't need to worry
            if ($slide.is(':visible')) return false;
            // Get it's height
            height = $slide.outerHeight(true);

            $(this).addClass('cur');
            $(this).siblings().removeClass('cur');

            // Fade out the current slide
            $slideshow.find('> div:visible').fadeOut(that.speed);
            // Animate the height gracefully to the new contents
            $slideshow.animate({ height: height }, that.speed);
            // Fade in the new slide
            $slide.fadeIn(that.speed);

        });

        this.nav_carousel();

    },

    nav_carousel: function() {
        var that = this,
            $nav = this.$gallery_blocks.find('.nav'),
            $pager = {},
            $intval = {},
            visible = 4,
            length = $nav.find('li').length
            width = $nav.find('li:first').outerWidth(true) * visible;

        // If there are more nav than we can see
        if (length > visible) {
            $pager = $('<div class="nav_pager horizontal">' +
                '<ul class="prev_next horizontal">' +
                    '<li class="prev"><a href="#">Prev</a></li>' +
                    '<li class="next"><a href="#">Next</a></li>' +
                '</ul>' +
            '</div> <!-- // .nav_pager -->');
            $intval = $('<ol class="intval" />');
            var i = 1,
                limit = Math.ceil(visible / length) + 1,
                css_class = 'cur';
            for (i; i<=limit; i++) {
                $intval.append($('<li class="' + css_class + '"><a href="#">' + i + '</a></li>'));
                css_class = '';
            }

            // Bind clicks to new pagers
            $intval.find('li').bind('click', function(e) {
                var eq = $(this).index();
                e.preventDefault();
                move(eq);
                $(this).addClass('cur');
                $(this).siblings().removeClass('cur');
                // console.log(eq);
            });

            $pager.find('.prev_next li').bind('click', function(e) {
                var eq = $intval.find('li.cur').index();
                eq = $(this).hasClass('next') ? eq + 1 : eq - 1;
                $intval.find('li:eq(' + eq + ')').trigger('click');
            });

            function move(eq) {
                var left = width * eq * -1;
                $nav.find('.wrapper').animate({ left: left });
            }

            $pager.prepend($intval);
            this.$gallery_blocks.find('.slides').after($pager);
        }

    },

    advance: function() {
        var $nav = this.$gallery_blocks.find('.nav');

        //Find next slide
        if( $nav.find('li.cur').next().length > 0  )
            $nav.find('li.cur').next().trigger('click');
        else
            $nav.find('li').first().trigger('click');
    }

};

/**
 * jQuery Chosen plugin
 *
 * Adds chosens to selected items
 */
EDJ.chosen = {
    $chosen: {},
    $chosen_deselect: {},
    
    run: function() {
        this.$chosen = $('.chzn-select');
        this.$chosen_deselect = $('chzn-select-deselect');
        return this.$chosen.length > 0 || this.$chosen_deselect.length > 0;
    },
    
    init: function() {
        this.$chosen.parent().addClass($.cookie('chzn'));
        this.$chosen.val("/state/"+$.cookie('chzn'));
        this.$chosen.chosen();
        this.$chosen_deselect.chosen({
            allow_single_deselect:true
        });
    }
};

/**
 * Quick jump
 *
 * Navigates to a select boxes value on change
 */
EDJ.quick_jump = {
    $quick_jump: {},

    run: function() {
        this.$quick_jump = $('select.quick_jump');
        return this.$quick_jump.length > 0;
    },

    init: function() {
        this.$quick_jump.bind('change', function() {
            $(this).parent().addClass($(this).val().substr(7,2));
            $.cookie('chzn', $(this).val().substr(7,2), { path: '/' });
            // alert($(this).val());
            window.location = $(this).val();
        });
    }
};

/**
 * jQuery tabs
 */
EDJ.ui_tabs = {
    $tabs: {},

    run: function() {
        this.$tabs = $('.ui_tabs');
        return this.$tabs.length > 0;
    },

    init: function() {
        this.$tabs.tabs({
        });
    }
};

/**
 * jQuery validation
 *
 * Uses classes to asses rules
 */
EDJ.validation = {
    $forms: {},

    run: function() {
        this.$forms = $('form.validate');
        return this.$forms.length > 0;

    },

    init: function() {
        this.$forms.each(function(i, f){
            $(f).validate({
                
            });
        });
    }
};


/**
 * Open YouTube urls in a modal
 */
EDJ.youtube_modal = {
    $links: {},

    run: function() {
        this.$links = $('.training_listing #content_pri a[href^="http://www.youtube.com/"], .training_listing #content_pri a[href^="http://youtube.com/"]');

        return this.$links.length > 0;
    },

    init: function() {
        this.$links.colorbox({
            iframe: true,
            href: function() {
                var url = $(this).attr('href');
                url = url.replace('watch?v=', 'embed/');
                return url;
            },
            innerWidth: '800',
            innerHeight: '476'
        });

    }
}

/**
 * Ajax pagination
 *
 * More results link will append results with AJAX
 */
EDJ.more_results_ajax = {
    $more_results: {},
    $post_container: {},

    run: function() {
        this.$more_results = $('.cta_button.more a');
        return this.$more_results.length > 0;
    },

    init: function() {
        var that = this;
        this.$post_container = $('#content_pri .item_listing:eq(0)');

        this.$more_results.live('click', function(e){
            var hash = $(this).attr('href').split('#')[1];
            e.preventDefault();

            // Don't proceed if we're already loading
            if ($(this).hasClass('loading')) return false;
            $(this).addClass('loading');
            $.ajax({
                url: $(this).attr('href'),
                success: function(data) {
                    var $content = {},
                        $more_btn = {},
                        section = (typeof(hash) == 'undefined') ? '#content_pri' : '#' + hash;

                    $content = $(data).find(section + ' .item_listing > li');
                    EDJ.log('Found extra ' + $content.length + ' items... appending');
                    $more_btn = $(data).find('.cta_button.more a');
                    if ($more_btn.length > 0) {
                        that.$more_results.attr('href', $more_btn.attr('href'));
                        that.$more_results.removeClass('loading');
                    } else {
                        EDJ.log('No more results, removing more button');
                        that.$more_results.parent().remove();
                    }
                    that.$post_container.append($content);

                }
            });
        });
    }
};


/**
 * Partners equal
 *
 * Ensure all partner logos have an equal height on their parent
 */
EDJ.partners_equal = {
    $partners: {},

    run: function() {
        this.$partners = $('#partners_gallery li');
        return this.$partners.length > 0;
    },

    init: function() {
        var max_height = 0;

        // First loop through to find the max height
        this.$partners.each(function() {
            var this_height = $(this).height();
            max_height = (this_height > max_height) ? this_height : max_height;
        });
        // Then loop again to set the images at the right height
        this.$partners.each(function() {
            var margin = (max_height - $(this).height()) / 2;
            $(this).find('img').css({
                position: 'relative',
                top: margin
            });
        });
        // Then set all the list items at the same height
        this.$partners.height(max_height);
    }
};

/**
 * Recruit add a friend
 *
 * Adds new lines of friends to form on recruit page
 */
EDJ.recruit_add_friend = {
    $add_friend: {},

    run: function() {
        this.$add_friend = $('.add_a_friend');
        return this.$add_friend.length > 0;
    },

    init: function() {
        this.$add_friend.delegate('a', 'click', function(e) {
            e.preventDefault();
            $(this).closest('div').next('.friend').show();
            $(this).parent('p').remove();
        });
    }

};

/**
 * SOAE forms
 *
 * Initializes the SOAE forms
 */
EDJ.soae = {
    $hash_tag: 'EN2012',
    $character_limit: 138, //twitter limit minus 2 for space and hashtag
    
    run: true,

    init: function() {
        var that = this;

        // Radio buttons / hashtag text toggle
        $('#soae_form div.hashtag p span').html('#'+this.$hash_tag);
        $('input.soae-twitter').click(function(){
            $('#soae_form div.hashtag').show(); 
        });

        $('input.soae-email').click(function(){
            $('#soae_form div.hashtag').hide(); 
        });
        
        // Character count
        $('div#soae-question span.character').html(this.$character_limit - this.$hash_tag.length);
        $('div#soae-question textarea').keyup(function(e){
            that.update_character_limit($(this));
        });

        // Open tweet window
        $('#ask-a-question').submit(function(){
            if( ( $('input.soae-twitter').attr('checked') == 'checked' ) && $(this).valid() )
            {
                tweet_text = $('#soae-question textarea').val();
                window.open( "https://twitter.com/intent/tweet?text="+tweet_text+"&hashtags="+that.$hash_tag, "myWindow", "status = 1, height = 400, width = 500, resizable = 0" );
                return true;
            }
        });

        // MX form
        $('#soae-mx-subscribe').submit(function(){
            if( $(this).valid() )
            {
                $('#soae-mx-subscribe label.required').html('<img src="/static/images/site/soae/loading.gif" alt="Loading" class="loading" />');
                //make first request to see if there is an existing member
                $.getJSON('https://admin.grassroots.com/api.dyn/page/getInfo?callback=?', {
                    'clientId': 3791,
                    'page': 'http://join.energynation.org/SOAE2012/',
                    'emailAddress': $('#soae-mx-subscribe-email').val()
                }, function(e){
                    if( e.status.code == 200 )
                    {
                        // preexisting member, just send the info flag
                        $.getJSON('https://admin.grassroots.com/api.dyn/page/takeAction?callback=?', {
                            'clientId': 3791,
                            'page': 'http://join.energynation.org/SOAE2012/',
                            'member.emailAddress': $('#soae-mx-subscribe-email').val(),
                            'member.unsubscribe': true,
                            'member.send2012SOAEWebcastEmails': "Yes" 
                        }, function(r){
                            if( r.status.code == 200 )
                            {
                               $('#soae-mx-subscribe').html('<strong>Thank you for signing up to receive updates.</strong>'); 
                            }
                        });
                    }
                    else
                    {
                        // preexisting member, just send the info flag
                        $.getJSON('https://admin.grassroots.com/api.dyn/page/takeAction?callback=?', {
                            'clientId': 3791,
                            'page': 'http://join.energynation.org/SOAE2012/',
                            'member.emailAddress': $('#soae-mx-subscribe-email').val(),
                            'member.unsubscribe': true,
                            'member.purgeAfter2012SOAEWebcast': "Yes",
                            'member.send2012SOAEWebcastEmails': "Yes" 
                        }, function(r){
                            if( r.status.code == 200 )
                            {
                               $('#soae-mx-subscribe').html('<strong>Thank you for signing up to receive updates.</strong>'); 
                            } 
                        });
                    }
                });
            }
            return false; 
        });
    },
    
    update_character_limit: function(textarea) {
        $character_count_span = EDJ.$body.find('div#soae-question span.character');
        
        $characters_left = this.$character_limit - this.$hash_tag.length - textarea.val().length;
        
        if($characters_left <= 0 )
            $character_count_span.addClass('error')
        else
            $character_count_span.removeClass('error');

        $character_count_span.html($characters_left);
    } 
};

