/**
 * Slideshow (slideshow.js)
 * Copyright (c) 2008 Jack Szwergold. All rights reserved.
 *
 * w: http://www.runwork.com
 * e: me@runwork.com
 *
 * Created: 2008-08-08
 * Version: 2009-12-04
 *
 */

  Event.observe(window, 'load', function () {
    window.Slide1 = new Slide('Slide1', '2', '2', 'spring', 'loop', 'width');
    //window.Slide1.Controls();

    // Transitions: linear, sinoidal, reverse, flicker, wobble, pulse, spring, full
    // new PeriodicalExecuter( function () { window.Slide1.Auto('random'); }, 1);
    // new PeriodicalExecuter( function () { window.Slide2.Auto('random', 'prev'); }, 1);
    // new PeriodicalExecuter( function () { window.Slide2.Auto('endless', 'prev'); }, 1);
    new PeriodicalExecuter( function () { window.Slide1.Auto('backforth', 'prev'); }, 6);
  });

  /************************************************************************************************/
  // Main Slideshow class.
  function Slide (id, frame, speed, transition, mode, axis) {
    this.count = (typeof(this.count) == 'undefined') ? 0 : this.count;
    this.id = id;
    this.frame = ((typeof(frame) != 'undefined') && (frame.length > 0)) ? Math.abs(frame) : 1;
    this.speed = ((typeof(speed) != 'undefined') && (speed.length > 0)) ? speed : '0.25';
    this.transition = ((typeof(transition) != 'undefined') && (transition.length > 0)) ? transition : 'linear';
    this.mode = ((typeof(mode) != 'undefined') && (mode.length > 0)) ? mode : 'slide';
    this.axis = ((typeof(axis) != 'undefined') && (axis.length > 0)) ? axis : 'width';


    /**********************************************************************************************/
    // Automatic function.
    this.Auto = function (auto_type, direction) {
      var auto_type = (typeof(auto_type) != 'undefined') ? auto_type : 'endless';
      var direction = (typeof(direction) != 'undefined') ? direction : 'next';

      // Bounce the items back and forth.
      if (auto_type == 'backforth') {
 	    var length = $$('#'+this.id+' > ul > li').length;
 	    increment = (typeof(increment) == 'undefined') ? 1 : increment;
 	    count = (typeof(count) == 'undefined') ? 0 : count;
        if (count == 0) { increment = 1 }
        if (count == (length - this.frame)) { increment = -1 }
        count = (count + increment) % length;
        var direction = (increment == 1) ? 'next' : 'prev';
      }
      else if (auto_type == 'random') {
        var direction = 'rand';
      }

      // Otherwise keep on showing items flowing in one direction.
      this.Show(direction);
	}


    /**********************************************************************************************/
    // Get the ret of the slides.
    this.Dimensions = function () {
      var x = 0;
      var ret = new Array();
      $$('#'+this.id+' > ul > li').each(function(item) {
        ret[x] = item.getDimensions();
        x++;
      });
    return ret;
    }


    /**********************************************************************************************/
    // Label the slides.
    this.Label = function () {
      var count = (typeof(count) == 'undefined') ? 1 : count;
      $$('#'+this.id+' > ul > li').each(function(item) {
        var control = new Element('div', { 'class': 'number', 'id': 'number'+count})
                    .setStyle({ 'position': 'absolute', 'fontSize': '80%', 'color': '#fff', 'backgroundColor': '#000', 'textAlign': 'center', 'right': '0', 'bottom': '0', 'padding': '3px 15px 3px 15px' })
                    .insert( {top:count});
        Element.insert($(item).down('div', 0), { bottom: control } );
        count++;
      });
    }


    /**********************************************************************************************/
    // Shows/hides controls based on whether it's a loop or not.
    this.Controls = function () {
      this.use_controls = true;
      if (this.mode != 'loop') {
        ($('prev_'+this.id) && (this.count > 0)) ? $('prev_'+this.id).setOpacity(1) : $('prev_'+this.id).setOpacity(0.1);
        ($('next_'+this.id) && (this.count < ($$('#'+this.id+' > ul > li').length-frame))) ? $('next_'+this.id).setOpacity(1) : $('next_'+this.id).setOpacity(0.1);
      }
    }


    /**********************************************************************************************/
    // Random function since JavaScript can't do such things right.
    this.Random = function (range, offset_real) {
      var offset = (typeof(offset_real) == 'undefined') ? 0 : offset_real;
	  return Math.floor(Math.random()*range)+offset;
	}

    /**********************************************************************************************/
    // Show function.
    this.Show = function (where_raw, jump_raw) {
      var where = (typeof(where_raw) == 'undefined') ? 'next' : where_raw;
      var jump = (typeof(jump_raw) == 'undefined') ? 0 : jump_raw;

      var frame = this.frame;
      var speed = this.speed;
      var transition = this.transition;
      var mode = (where == 'rand' && this.mode == 'loop') ? 'slide' : this.mode;
      var axis = this.axis;

      var elements = $$('#'+this.id+' > ul > li');
      var offset = 1;

      // This calculates the this.frame size and adjusts the jump and offset so there is no empty spaces.
      if (((this.count > (elements.length-frame)-1) && (where == 'next'))  || (jump > (elements.length-frame)) && (where != 'prev')) {
        var jump = (elements.length-frame);
        var offset = 0;
      }

      // Calculate random jumps.
      if (where == 'rand') {
        // The switch at the end of is an adjustment if there is a random trigger for a looped list.
        var prev_range = this.count-((where == 'rand' && this.mode == 'loop') ? 1 : 0);
        var next_range = ((elements.length-this.count)-frame+1);

        if (jump == 'prev') {
          // var jump = (prev_range == 0) ? elements.length-frame : this.Random(prev_range);
          var jump = this.Random(prev_range);
        }
        else if (jump == 'next') {
          // var jump = (next_range <= 1) ? 0 : this.Random(next_range, prev_range);
          var jump = this.Random(next_range, prev_range);
        }
        else {
          var jump = this.Random(elements.length-frame);
        }

        var where = 'jump';
      }

      // Calculate a standard jumps.
      if (where == 'jump') {
        var offset = Math.abs(jump-this.count);
        var where = (jump-this.count < 0) ? 'prev' : 'next';
        if (offset == 0) {
          new Effect.Pulsate(elements[jump].down(0), { pulses: 1, duration: 0.125, delay: 0, queue: 'end', scope: this.id, limit: 1, speed: speed });
        }
      }

      var elements_real = (where == 'prev') ? elements : elements.reverse();
      // var dimensions_real = (where == 'prev') ? this.Dimensions() : this.Dimensions().reverse();
      var dimensions_real = this.Dimensions();


      /********************************************************************************************/
      // Loop through the list.

      if (mode == 'loop') {
        var loop_from = (where == 'prev') ? (elements_real.length-1) : 0;
        var loop_list = $(this.id);
        // var loop_element = $(this.id).down('li', loop_from);
        var loop_element = $(this.id).down('ul', 0).childElements()[loop_from];
        var loop_dimensions = loop_element.getDimensions();

        // for (var x = 0; x < offset; x++) {
        // $('Info').insert(offset+'<br />');
        // }

        var shift_each = -loop_dimensions[axis];
        var x_shift = (axis == 'width') ? shift_each : 0;
        var y_shift = (axis == 'height') ? shift_each : 0;

        if (where == 'next') {
          new Effect.Morph(loop_element, { style: { marginLeft: x_shift+'px', marginTop: y_shift+'px' }, duration: speed, queue: 'front', scope: this.id, limit: 1, transition: Effect.Transitions[transition],
            afterFinish: function() {
              new Element.insert(loop_list.down('ul', 0), { bottom: loop_element } );
              new Element.setStyle(loop_element, { marginLeft: '0px', marginTop: '0px' });
            }
          });
        }
        else if (where == 'prev') {
          new Effect.Morph(loop_element, { style: { marginLeft: '0px', marginTop: '0px' }, duration: speed, queue: 'front', scope: this.id, limit: 1, transition: Effect.Transitions[transition],
            beforeStart: function() {
              new Element.insert(loop_list.down('ul', 0), { top: loop_element } );
              new Element.setStyle(loop_element, { marginLeft: x_shift+'px', marginTop: y_shift+'px' });
            }
          });
        }
      }

      /********************************************************************************************/
      // Old method of sliding the whole 'ul'.

      else if ((mode == 'slide') && ((this.count < (elements.length-1)) && (where == 'next')) || ((this.count > 0) && (where == 'prev'))) {
        var shift_all = 0;
        for (var x = 0; x < offset; x++) {
          var shift_each = (where == 'prev') ? dimensions_real[this.count-1][axis] : -dimensions_real[this.count][axis];
          if (typeof(shift_each) != 'undefined') {
            var shift_all = shift_all + shift_each;
            (where == 'prev') ? this.count--: this.count++;
          }
        }
        var x_shift = (axis == 'width') ? shift_all : 0;
        var y_shift = (axis == 'height') ? shift_all : 0;
        new Effect.Move($(this.id).down('ul'), { x: x_shift, y: y_shift, duration: speed, queue: 'front', scope: this.id, limit: 1,
          transition: Effect.Transitions[transition]
        });
      }

      (typeof(this.use_controls) != 'undefined') ? this.Controls() : '';

    }

  }