/**
 * mTheatre ist eine Art DIV-Slide Show
 *
 * Abhängig von MooTools v1.2
 *
 * @encoding  utf-8
 *
 * @category  Effects
 * @author    Matthias Göbels <goebels@medienpark.net>
 * @version   14.10.2008 RC 1.0
 * @copyright 2008 medienPARK GmbH & Co.KG.
 */
var mTheatre = new Class(
{
  /**
   * Initialisiert die Slide Show
   *
   * Sorgt dafür, dass die Slide Show genutzt und angezeigt
   * werden kann und Basisdaten wie z.B. die Optionen zur
   * Verfügung stehen.
   *
   * Verfügbare Optionen:
   * - automation          boolean          Schalter um die automatische Animation an- und abzuschalten
   * - direction           forward|backward enthält die Richtung der automatischen Animation. Standardmässig ist 'forward' aktiviert
   * - duration            integer          enthält die Dauer der Animation in Millisekunden
   * - linkImageLeft       string           URL des Link Overlay Bildes - Links
   * - linkImageLeftHover  string           URL des Link Overlay Hover Bildes - Links
   * - linkImageRight      string           URL des Link Overlay Bildes - Rechts
   * - linkImageRightHover string           URL des Link Overlay Hover Bildes - Rechts
   * - links               boolean          Schalter zum an- und abschalten der überlagerten Verlinkung
   * - pauseDuration       integer          enthält die Dauer der Pause zwischen den Animationen in Millisekunden
   * - transitionPrev      Fx.Transitions   enthält die Animationsart aus Fx.Transitions für das Zurückblättern
   * - transitionNext      Fx.Transitions   enthält die Animationsart aus Fx.Transitions für das Vorblättern   
   * 
   * @param string elementID enthält den Identifizierungsstring des Äußeren DIV's
   *                         auf welches die Slide-Show angewandt werden soll.
   * @param arrray options   enthält die Optionen die für diese Instanz der Slide Show
   *                         angewandt werden sollen.
   */
  initialize: function(el, options)
  {
    this.setOptions(
      {
        transitionPrev: Fx.Transitions.linear,
        transitionNext: Fx.Transitions.linear,
        duration: 300,
        direction: 'forward', // 'backward'
        automation: false, // false
        pauseDuration: 5000,
        links: true,
        linkImageLeft: '',
        linkImageLeftHover: '',
        linkImageRight: '',
        linkImageRightHover: ''
      },
      options
    );
    
    // Eigenschaften initialisieren 
    this.theatre = $(el);
    this.children = this.theatre.getChildren();
    this.theatre.setStyle('overflow', 'hidden');
    this.size = this.theatre.getSize();
    this.currentPosition = 0;
    this.delay = null;
    this.naviLeft = null;
    this.naviRight = null;
    
    this.prepare();
    
    // Stösst die automatische Animation an
    if(this.options.automation)
    {
      if(this.options.direction == 'forward')
      {
        $clear(this.delay);
        this.delay = this.next.bind(this).delay(this.options.pauseDuration);
      }
      else
      {
        $clear(this.delay);
        this.delay = this.prev.bind(this).delay(this.options.pauseDuration);
      }
    }
  },
  
  /**
   * Bereitet die DOM-Elemente auf
   *
   * Passt die Dimensionen der Elmente an und Positioniert diese richtig im DOM
   */
  prepare: function()
  {
    this.theatre.getChildren().each(
      function(el)
      {
        el.dispose();
      }
    );
    
    this.animationScene = new Element('div');
    this.animationScene.setStyles(
      {
        display: 'block',
        width: (this.size['x'] * 2),
        height: this.size['y'],
        'float': 'left'
      }
    );
    this.animationScene.injectInside(this.theatre);
    
    this.children.each(
      function(el)
      {
        el.setStyles(
          {
            display: 'block',
            width: this.size['x'],
            height: this.size['y'],
            'float': 'left',
            'overflow': 'hidden'
          }
        );
      }.bind(this)
    );
    
    var newElement = this.children[0].clone();
    newElement.injectInside(this.animationScene);
    this.currentElement = newElement;
    
    if(this.options.links)
    {
      this.prepareLinks();
    }
  },
  
  addLinkEvents: function()
  {
    if(this.options.links == true)
    {
      this.naviLeft.addEvents(
        {
          'click': function()
          {
            this.prev();
          }.bind(this),
          'mouseover': function()
          {       
            this.naviMouseOver(this.options.linkImageLeft, this.options.linkImageLeftHover, this.naviLeft);
          }.bind(this),
          'mouseout': function()
          {
            this.naviMouseOut(this.options.linkImageLeft, this.options.linkImageLeftHover, this.naviLeft);
          }.bind(this)
        }
      );
      
      this.naviRight.addEvents(
        {
          'click':
          function()
          {
            this.next();
          }.bind(this),
          'mouseover': function()
          {       
            this.naviMouseOver(this.options.linkImageRight, this.options.linkImageRightHover, this.naviRight);
          }.bind(this),
          'mouseout': function()
          {
            this.naviMouseOut(this.options.linkImageRight, this.options.linkImageRightHover, this.naviRight);
          }.bind(this)
        }
      );
    }
  },
  
  removeLinkEvents: function()
  {
    if(this.options.links == true)
    {
      this.naviLeft.removeEvents();
      this.naviRight.removeEvents();
    }
  },

  /**
   * Erstellt die Verlinkung über der Animation zur Weiterschaltung
   */
  prepareLinks: function()
  {
    // Verlinkung links
    this.naviLeft = new Element('a');
    this.naviLeft.href = 'javascript: void(0);';
    
    if(this.options.linkImageLeft != null && this.options.linkImageLeftHover == null)
    {
      var opac = '0.5';
    }
    if(this.options.linkImageLeft != null && this.options.linkImageLeftHover != null)
    {
      var opac = '1.0';
    }
    this.naviLeft.setStyles(
      {
        display: 'block',
        width: (Math.round(this.size['x'] * 0.15) + 'px'),
        height: this.size['y'],
        backgroundColor: 'transparent',
        position: 'absolute',
        zIndex: '20',
        top: this.theatre.getTop(),
        left: this.theatre.getLeft(),
        opacity: opac,
        backgroundImage: 'url(' + this.options.linkImageLeft + ')',
        backgroundPosition: 'center center',
        backgroundRepeat: 'no-repeat',
        outline: 'none'
      }
    );

    this.naviLeft.injectInside(document.body);
    
    // Verlinkung rechts
    this.naviRight = new Element('a');
    this.naviRight.href = 'javascript: void(0);';
    if(this.options.linkImageRight != null && this.options.linkImageRightHover == null)
    {
      var opac = '0.5';
    }
    if(this.options.linkImageRight != null && this.options.linkImageRightHover != null)
    {
      var opac = '1.0';
    }
    this.naviRight.setStyles(
      {
        display: 'block',
        width: (Math.round(this.size['x'] * 0.15) + 'px'),
        height: this.size['y'],
        backgroundColor: 'transparent',
        position: 'absolute',
        zIndex: '20',
        top: this.theatre.getTop(),
        left: ((this.theatre.getLeft() + this.size['x'] - Math.round(this.size['x'] * 0.15)) + 'px'),
        opacity: opac,
        backgroundImage: 'url(' + this.options.linkImageRight + ')',
        backgroundPosition: 'center center',
        backgroundRepeat: 'no-repeat',
        outline: 'none'
      }
    );
    
    this.naviRight.injectInside(document.body);
    this.addLinkEvents();
  },
  
  /**
   * Event Handling für das Mouseover der Animation
   */
  naviMouseOver: function(linkImage, linkImageHover, navi)
  {
    if(linkImage != null && linkImageHover == null)
    {
      navi.setStyles(
        {
          opacity: '1'
        }
      );
    }
    if(linkImageHover != null)
    {
      navi.setStyles(
        {
          backgroundImage: 'url(' + linkImageHover + ')'
        }
      );
    }
  },
  
  /**
   * Event Handling für das Mouseout der Animation
   */
  naviMouseOut: function(linkImage, linkImageHover, navi)
  {
    if(linkImage != null && linkImageHover == null)
    {
      navi.setStyles(
        {
          opacity: '0.5'
        }
      );
    }
    if(linkImageHover != null)
    {
      navi.setStyles(
        {
          backgroundImage: 'url(' + linkImage + ')'
        }
      );
    }
  },
  
  /**
   * "Blättert" die Animation weiter
   *
   * Startet die Animation zur Anzeige der nächsten Seite.
   */
  next: function()
  {
    this.removeLinkEvents();
    if(this.options.automation)
    {
      $clear(this.delay);
    }
    var nextPos = this.currentPosition + 1;
    if(nextPos >= this.children.length)
    {
      nextPos = 0;
    }
    
    this.currentElement.setStyles({ 'zIndex': 10 });
    var newElement = this.children[nextPos].clone();
    newElement.setStyles({opacity: 1.0, 'zIndex' : 1000});
    newElement.injectInside(this.animationScene);
    var aniHelper = { 'nextPos': nextPos, 'newElement': newElement, obj: this };
    
    var fx = null;
    fx = new Fx.Morph(this.currentElement, { duration: this.options.duration, transition: this.options.transitionNext });
    fx.start(
      {
        width: '0px',
        opacity: 0.0
      }
    ).chain(
      function()
      {
        aniHelper.obj.currentElement.dispose();
        aniHelper.obj.currentPosition = aniHelper.nextPos;
        aniHelper.obj.currentElement = aniHelper.newElement;
        aniHelper.obj.currentElement.setStyles(
          {
            display: 'block',
            width: aniHelper.obj.size['x'],
            height: aniHelper.obj.size['y'],
            'float': 'left'
          }
        );
        if(aniHelper.obj.options.automation)
        {
          if(aniHelper.obj.options.direction == 'forward')
          {
            $clear(aniHelper.obj.delay);
            aniHelper.obj.delay = aniHelper.obj.next.bind(aniHelper.obj).delay(aniHelper.obj.options.pauseDuration);
          }
          else
          {
            $clear(aniHelper.obj.delay);
            aniHelper.obj.delay = aniHelper.obj.prev.bind(aniHelper.obj).delay(aniHelper.obj.options.pauseDuration);
          }
        }
        aniHelper.obj.addLinkEvents();
      }.bind(aniHelper)
    );
  },
  
  /**
   * "Blättert" die Animation zurück
   *
   * Startet die Animation zur Anzeige der vorherigen Seite.
   */
  prev: function()
  {
    this.removeLinkEvents();
    if(this.options.automation)
    {
      $clear(this.delay);
    }
    var nextPos = this.currentPosition - 1;
    if(nextPos < 0)
    {
      nextPos = (this.children.length - 1);
    }
    
    var newElement = this.children[nextPos].clone();
    newElement.setStyles({'width': '0px', opacity: 1.0});
    newElement.injectBefore(this.currentElement);
    var aniHelper = { 'nextPos': nextPos, 'newElement': newElement, obj: this };
    
    var fx = new Fx.Morph(newElement, { duration: this.options.duration, transition: this.options.transitionPrev });
    var fx2 = new Fx.Morph(this.currentElement, { duration: this.options.duration, transition: this.options.transitionPrev });
    fx2.start(
      {
        opacity: 0.0
      }
    );
    fx.start(
      {
        width: this.size['x']
      }
    ).chain(
      function()
      {
        aniHelper.obj.currentElement.dispose();
        aniHelper.obj.currentPosition = aniHelper.nextPos;
        aniHelper.obj.currentElement = aniHelper.newElement;
        if(aniHelper.obj.options.automation)
        {
          if(aniHelper.obj.options.direction == 'forward')
          {
            $clear(aniHelper.obj.delay);
            aniHelper.obj.delay = aniHelper.obj.next.bind(aniHelper.obj).delay(aniHelper.obj.options.pauseDuration);
          }
          else
          {
            $clear(aniHelper.obj.delay);
            aniHelper.obj.delay = aniHelper.obj.prev.bind(aniHelper.obj).delay(aniHelper.obj.options.pauseDuration);
          }
        }
        aniHelper.obj.addLinkEvents();
      }.bind(aniHelper)
    );
  }
});

// Das mTheatre Objekt um das Options Objekt erweitern
mTheatre.implement(new Options);