if (!jQuery.fn.hasClassRegExp) {

    jQuery.fn.extend({
        hasClassRegExp : function (regexp) {
            var results = [];
            
            this.each(function(i, ele){ var r = new RegExp(regexp).exec(ele.className); if (r) results.push(r); })
            
            if (results.length)
                return results;
            else
                return;
        }
    });
}

jQuery.extend({
    delegate : function(obj, fun){ return function(){ var args = jQuery.makeArray(arguments); fun.apply(obj, args) };}
});


/**
* Home page Hero spot animator
*/

function Slideshow(slideshow_container_p, slideshow_controls_container_p) {
    this.slideshow_container = jQuery(slideshow_container_p).get(0);
    this.slideshow_controls_container = '';
    
    if (slideshow_controls_container_p)
        this.slideshow_controls_container = jQuery(slideshow_controls_container_p).get(0);
    
    if (this.slideshow_container)
        this.initialize();
}

jQuery.extend(Slideshow.prototype, {
    current_slide : '',
    slides        : [],
    
    slide_start_css : {
        'slide' : { opacity : 1 }   // same as in CSS
    },
    
    slide_remove_animation : {
        'slide' : {
            params   : { opacity : 0 },
            duration : 350
        }
    },
    
    auto_slide       : true,
    user_interacting : false,
    
    random           : false,
    
    auto_slide_delay : 4
});

/*
* initialize(e)
*/
Slideshow.prototype.initialize = function(e) {

    this.get_options();
    
    var slides = jQuery('>li', this.slideshow_container).not('.first').get();
    
    if (this.random)
        slides.sort(function(a,b){return Math.random()>.5});
    
    slides = [].concat(jQuery('>li.first', this.slideshow_container).get(), slides);
    
    // only one slide. don't do anything
    if (slides.length < 2)
        return;
    
    this.slides = [];
    
    if (this.slideshow_controls_container) {
        jQuery(this.slideshow_controls_container).append(this.create_control_buttons(slides.length, 0, 1));
        this.setup_control_buttons();
    }
    
    // combine elements into single object for easy access
    // if some elements are missing, then the object won't be created
    for (var i = 0; i < slides.length; i++) {
        
        var duration = this.get_duration_option(slides[i]);
        
        if (!duration || (duration < 0)) duration = this.auto_slide_delay;
        
        var slide = {
            index           : i,
            'duration'      : duration,
            slide_body      : slides[i]
        };
        
        this.slides.push(slide);
    }
    
    // if none, stop here and do nothing
    if (!this.slides.length) return;
    
    // choose random first one
    this.current_slide = this.slides[0];
    this.updateControls();
    
    // remove all but the chosen from the dom
    for (var i = 0; i < this.slides.length; i++) {
        // remove all but the chosen one from the dom
        
        if (i != this.current_slide.index) {
            jQuery(this.slides[i].slide_body).remove();
        }
    }
    
    // add handlers to slide, as they are lost when removed from dom
    this.add_handlers_to_slide(this.current_slide.slide_body);
    jQuery(this.current_slide.slide_body).css({ visibility : 'visible' });
    
    // if only one, don't animate, and hide controls
    //if (this.slides.length == 1)
    this.auto_slideshow_begin();
}

/*
* get_options()
*/
Slideshow.prototype.get_options = function() {
    // get options out of the className of the ul element
    var slide_container = this.slideshow_container;
    
    this.random = jQuery(slide_container).hasClass('random');
    
    var duration = this.get_duration_option(slide_container)
    
    if (duration)
        this.auto_slide_delay = duration;
}

/*
* get_duration_option(element)
*/
Slideshow.prototype.get_duration_option = function(dom_element) {
    var regexp_results = jQuery(dom_element).hasClassRegExp(/\bduration-([0123456789.]+)/);
    
    if (regexp_results && regexp_results[0])
        return regexp_results[0][1];
    else
        return;
}

/*
* setup_control_buttons(length)
*/
Slideshow.prototype.setup_control_buttons = function() {
    //
    // Control Button Handlers
    //
    jQuery('.heroslideshowcontrols .control a', this.slideshow_controls_container).hover( jQuery.delegate(this, this.handle_hero_interact_over), jQuery.delegate(this, this.handle_hero_interact_out) );
    
    var control_buttons = jQuery('.heroslideshowcontrols .control a', this.slideshow_controls_container);
    var direction_left  = 1; //jQuery(slide_body).hasClass('left');
    
    var cb_index = 0;
    var direction = 1;
    
    if (!direction_left) {
        cb_index = control_buttons.length - 1;
        direction = -1;
    }
    
    for (var j = 0; j < control_buttons.length; j++) {
        jQuery(control_buttons[j]).data('index', cb_index);
        
        jQuery(control_buttons[j]).click(jQuery.delegate(this, this.handle_control_button_click));
        cb_index += direction;
    }
}

/*
* create_control_buttons(length)
*/
Slideshow.prototype.create_control_buttons = function(length, selected, direction_left) {
    var lis = [];
    
    var number = 1;
    var direction = 1;
    
    if (!direction_left) {
        number = length;
        direction = -1;
    }
    
    for (var i = 0; i < length; i++) {
        var classname = '';
        
        lis.push('<li class="control"><a href="#"><span>' + number + '</span></a></li>');
        
        number += direction;
    }
    
    return '<ul class="heroslideshowcontrols">' + lis.join('') + '</ul>';
}

/*
* add_handlers_to_slide(length)
*/
Slideshow.prototype.add_handlers_to_slide = function(slide_body) {

    // user might be trying to click a link
    jQuery(slide_body).hover( jQuery.delegate(this, this.handle_hero_interact_over), jQuery.delegate(this, this.handle_hero_interact_out) );
}

/*
* show_slide(index)
*/
Slideshow.prototype.show_slide = function(new_slide_index) {
    var current_slide = this.current_slide;
    
    if (current_slide && (current_slide.index == new_slide_index))
        return;
    
    var new_slide = this.slides[new_slide_index];
    
    if (!new_slide)
        return;
    
    if (this.animating)
        return;
    
    /** toggle globals **/
    this.previous_slide = current_slide;
    this.current_slide  = new_slide;
    this.animating      = true;
    
    this.updateControls();
    
    // put new one under current one
    jQuery(current_slide.slide_body).before(new_slide.slide_body);
    
    jQuery(new_slide.slide_body).css({ visibility : 'visible' });
    
    // set elements' starting CSS so it's visible
    jQuery(new_slide.slide_body).css(this.slide_start_css['slide']);
    
    // readd handlers to slide, as they are lost when removed from dom
    this.add_handlers_to_slide(new_slide.slide_body);
    
    var delay = new_slide.duration;
    
    if (delay <= 0) delay = 4;
    
    // convert to miliseconds
    delay = delay * 1000;
    
    // add in time for the animation of going away
    delay += this.slide_remove_animation['slide'].duration;
    
    this.slide_wait(delay);
    
    /**
    * Begin go-away animations
    */
    // go away
    jQuery(current_slide.slide_body).animate(
        this.slide_remove_animation['slide'].params,
        this.slide_remove_animation['slide'].duration,
        'linear',
        jQuery.delegate(this, this._finish_showing_new_slide)
    );
}

/*
* updateControls()
*/
Slideshow.prototype.updateControls = function() {
    // button highlight
    if (this.slideshow_controls_container) {
        jQuery('.heroslideshowcontrols .control a', this.slideshow_controls_container).removeClass('selected');
        jQuery(jQuery('.heroslideshowcontrols .control a', this.slideshow_controls_container).get(this.current_slide.index)).addClass('selected');
    }
}

/*
* _finish_showing_new_slide()
*/
Slideshow.prototype._finish_showing_new_slide = function(new_slide_index) {
    if (this.previous_slide) {
        jQuery(this.previous_slide.slide_body).remove();
        this.previous_slide = '';
    }
    
    this.animating = false;
}

/**
* Auto Slideshow Related Functions
*/

/*
* auto_slideshow_begin()
*/
Slideshow.prototype.auto_slideshow_begin = function() {
    if (!this.auto_slide)
        return;
    
    // already started? don't start twice
    if (this.auto_slide_timeout)
        return;
    
    var delay = this.current_slide.duration;
    
    if (delay <= 0) delay = 4;
    
    delay = delay * 1000;
    
    // add in time for the animation of going away
    delay += this.slide_remove_animation['slide'].duration;
    
    this.slide_wait(delay);
}

/*
* auto_slideshow_show_next_slide()
*/
Slideshow.prototype.auto_slideshow_show_next_slide = function() {
    if (!this.auto_slide)
        return;
    
    // go slowly. don't clobber other running animation
    if (this.animating)
        return;
    
    // don't move if the user is trying to click something
    if (this.user_interacting) {
        this.slide_wait(1000); // wait for a second and recheck if the user un-hovered
        return;
    }
    
    var next_index = (this.current_slide.index + 1) % this.slides.length;
    
    // should never happen, but make sure we're not trying to go to the same slide
    // (that would mean there is only one slide, and the slideshow would never have been started)
    if (next_index == this.current_slide_index)
        return;
    
    this.show_slide(next_index);
}

/*
* auto_slideshow_end()
*/
Slideshow.prototype.auto_slideshow_end = function() {
    this.auto_slide = false;
    
    clearTimeout(this.auto_slide_timeout);
    
    this.auto_slide_timeout = false;
}

/*
* slide_wait(delay_in_milli_seconds)
*/
Slideshow.prototype.slide_wait = function(delay_in_milli_seconds) {
    clearTimeout(this.auto_slide_timeout);
    this.auto_slide_timeout = setTimeout(jQuery.delegate(this, this.auto_slideshow_show_next_slide), delay_in_milli_seconds);
}

/**
* Handlers
*/

/*
* handle_control_button_click(e)
*/
Slideshow.prototype.handle_control_button_click = function(e) {
    e.preventDefault();
    
    var control_button = jQuery(e.target).closest('a').get(0);
    
    var index = jQuery(control_button).data('index');
    
    this.auto_slideshow_end();
    
    this.user_interacting = false;
    
    this.show_slide(index);
    
    return false;
}

/*
* handle_hero_interact_over(e)
*/
Slideshow.prototype.handle_hero_interact_over = function(e) {
    this.user_interacting = true;
}

/*
* handle_hero_interact_out(e)
*/
Slideshow.prototype.handle_hero_interact_out = function(e) {
    this.user_interacting = false;
}

/**
* call initialize() when document is loaded
*/
jQuery(document).ready(function(){
    if (jQuery('#slideshowlist-container').css('display') != 'none') {
        new Slideshow('#slideshowlist>ul', '#slideshow-controls');
        new Slideshow('#news-wrap>ul');
    }
});


