
var MarinoSlider = function(viewport, panels, options) {
  var viewport, panels, tray, options, slots = [], index=0, busy=false, executor, xdelta = 0, ydelta = 0;
  var init = function() {
    options = set_default(options, {});
    options.width = set_default(options.width, 0);
    options.height = set_default(options.height, 0);
    options.direction = set_default(options.direction, 'left');
    options.duration = set_default(options.duration, 1);
    options.interval = set_default(options.interval, 1);
    options.autostart = set_default(options.autostart, true);

    if(options.width==0||options.height==0)
      throw 'please specify a width and height for your slider';
    if((options.interval+options.duration)==0)
      throw 'zero timed sliders are not sliders';

    switch(options.direction)
    {
      case 'left':  xdelta = options.width *-1;break;
      case 'right': xdelta = options.width * 1;break;
      case 'up':    ydelta = options.height*-1;break;
      case 'down':  ydelta = options.height* 1;break;
    }

    slots[0] = new Element('div', {'style':'float:left;width:'+options.width+'px;height:'+options.height+'px;'});
    slots[1] = new Element('div', {'style':'float:left;width:'+options.width+'px;height:'+options.height+'px;'});

    var w=options.width*2;
    var h=options.height;
    if(options.direction == 'up' || options.direction == 'down')
    {
      w=options.width;
      h=options.height*2;
    }

    tray = new Element('div', {'style':'display:block;width:'+w+'px;height:'+h+'px;'});
    viewport.insert(tray);
    viewport.style.overflow = 'hidden';
    viewport.style.width=options.width;
    viewport.style.height=options.height;

    slots[0].innerHTML = panels[0].innerHTML;
    slots[1].innerHTML = panels[1].innerHTML;

    if(options.direction == 'right' || options.direction == 'down') {
      tray.insert(slots[1]);
      tray.insert(slots[0]);
      new Effect.Move(tray, { x: xdelta*-1, y: ydelta*-1, mode: 'relative', duration: 0 });
    } else {
      tray.insert(slots[0]);
      tray.insert(slots[1]);
    }

    if(options.autostart)
      start();
  }

  var slide = function() {
    if(busy) { log('cant slide, busy'); return; }
    busy=true;
    new Effect.Move(tray, { x: xdelta, y: ydelta, mode: 'relative', afterFinish: resetTrayPosition, duration: options.duration });
    index++;
  }

  var resetTrayPosition = function() {
    slots[0].innerHTML = slots[1].innerHTML;
    new Effect.Move(tray, { x: xdelta*-1, y: ydelta*-1, mode:'relative', duration: 0, afterFinish: scheduleNextPanel});
  }

  var scheduleNextPanel = function(){
    if(index==panels.size())
      index=0;
    var next=0;
    if(index<panels.size()-1)
      next = index+1;
    slots[1].innerHTML = panels[next].innerHTML;
    busy=false;
  }

  var start = function() {
    if(!executor || !executor.timer) {
      log('start');
      executor=new PeriodicalExecuter(slide, options.interval+options.duration);
    }
  }
  var stop = function() {
    if(executor && executor.timer) {
      log('stop');
      executor.stop();
    }
  }

  var id = function() {
    return viewport.id;
  }

  var log = function(s) {
    if(typeof(console) != "undefined" && typeof(console.log) != "undefined")
      console.log('MarinoSlider:'+id()+':'+s);
  }

  var set_default = function(obj, default_value)
  {
    if(typeof(obj) == 'undefined')
    {
      return default_value;
    }
    return obj;
  }
  
  init();
  return {
    start: start,
    stop: stop,
    id: id
  };
}
