/*
  Slideshow com prototype e scriptaculous
  Como utilizar:
  
    <script src="prototype.js"></script>
    <script src="effects.js"></script>
    <script src="slideshow.js"></script>

    <div class="slideshow" id="slideshow">
      <div class="a"><img src="slide1.jpg"></div>
      <div class="b"><img src="slide2.jpg"></div>
      <div class="c"><img src="slide3.jpg"></div>
    </div>

    <script type="text/javascript">
    
    var slideShow = new Slideshow.Local('slideshow', null, 
                                                      { randomize:    false,
                                                        repeat:       true,
                                                        effectPair:   'grow',
                                                        showOptions:  { queue: {position:'front', scope: 't', limit:2}},
                                                        hideOptions:  { queue: {position:'end', scope: 't', limit:2}}
                                                        }
                                                        );
    </script> 
*/

var Slideshow = {};
Slideshow.Options = {
  effectPairs: {
    appear: {
      show:   function (element, options) {
        new Effect.Appear(element, options);
      },
      hide:    function (element, options) {
        new Effect.Fade(element, options);
      }
    },
    grow: {
      show:   function (element, options) {
         Effect.Grow(element, options);
      },
      hide:    function (element, options) {
         Effect.Shrink(element, options);
      }
    },
    blind: {
      show:   function (element, options) {
        new Effect.BlindDown(element, options);
      },
      hide:    function (element, options) {
        new Effect.BlindUp(element, options);
      }
    },
    slide: {
      show:   function (element, options) {
        new Effect.SlideDown(element, options);
      },
      hide:    function (element, options) {
        new Effect.SlideUp(element, options);
      }
    },
    simple: {
      show:   function (element, options) {
        Element.show(element);
      },
      hide:    function (element, options) {
        Element.hide(element);
      }
    }
  },
  defaults: {
    minFrames:      2,
    delay:          5,
    randomize:      false,
    repeat:         false,
    effectPair:     'appear',
    showEffect:     null,
    showOptions:    {},
    hideEffect:     null,
    hideOptions:    {},
    beforeChange:   null,
    afterChange:    null,
    startPaused:    false,
    frames: 		null
  }
};

Effect.Slideshow = Class.create();
Object.extend(Object.extend(Effect.Slideshow.prototype, Effect.Base.prototype), {
  initialize: function (element, options) {
    this.element = $(element);
    this._shared_initialize(options);
  },
  _shared_initialize: function (options) {
    Element.cleanWhitespace(this.element);

    this.options = Slideshow.Options.defaults;
    Object.extend(this.options, options);
    if (this.options.showEffect && this.options.hideEffect) {
      this._effectPair = {
        show:   this.options.showEffect,
        hide:   this.options.hideEffect
      };
    }
    else if (this.options.effectPair == 'random') {
      this._usedEffectPairs    = [];
      this._unusedEffectPairs  = [];
      for (type in Slideshow.Options.effectPairs) {
        this._unusedEffectPairs.push(type);
      }
    }
    else if (Slideshow.Options.effectPairs[this.options.effectPair]) {
      this._effectPair = Slideshow.Options.effectPairs[this.options.effectPair];
    }
    else {
      throw('Slideshow requires a valid effectPair or showEffect AND hideEffect to work');
    }
    this.options.delay = parseInt(this.options.delay * 1000);
    this._isRandom = this.options.randomize;

    var showTime = parseInt((this.options.showOptions.duration || 1.0) * 1000);
    var hideTime = parseInt((this.options.hideOptions.duration || 1.0) * 1000);
    if (showTime > hideTime) {
      this.options.delay += showTime;
    }
    else {
      this.options.delay += hideTime;
    }

    this._usedFrames   = [];
    
    if (this.options.frames) {
	    this._unusedFrames = $A(this.options.frames);
	    this._allFrames = this.options.frames;
    }
    else {
	    this._unusedFrames = $A(this.element.childNodes);
	    this._allFrames = $A(this.element.childNodes);
    }
    
    this._unusedFrames.each( function (el) { Element.hide(el); } );

    this.isPaused = this.options.startPaused || false;
    this.isDone   = false;
    
    this._nextFrame();
  },
  _getNextFrame: function () {
    if (! this._unusedFrames.length) {
      if (this.options.repeat && this._usedFrames.length) {
        this._unusedFrames = this._usedFrames;
        this._usedFrames   = [this._unusedFrames.pop()];
      }
      else {
        this.isDone = true;
        return null;
      }
    }

    var nextFrame = null;
    var numUnused = this._unusedFrames.length;
    if (this._isRandom && numUnused > 1) {
      var index = Math.floor(Math.random()*numUnused);
      nextFrame = this._unusedFrames[index];
      this._unusedFrames.splice(index, 1);
    }
    else {
      nextFrame = this._unusedFrames.shift();
    }
    this._usedFrames.push(nextFrame);

    return nextFrame;
  },
  _nextFrame: function () {
    if (! this.isPaused) {
      this._changeFrame();
    }
  },
  _changeFrame: function () {
    var newFrame = this._getNextFrame();
    if (newFrame) {
    
      var currentIndex = this._allFrames.indexOf(newFrame);

      if (this.options.beforeChange) {
        this.options.beforeChange(this, currentIndex);
      }

      if (this.options.effectPair == 'random') {
        if (! this._unusedEffectPairs.length) {
          this._unusedEffectPairs  = this._usedEffectPairs;
          this._usedEffectPairs    = [ this._unusedEffectPairs.pop() ];
        }
        if (this._unusedEffectPairs.length) {
          var index = Math.floor(Math.random()*this._unusedEffectPairs.length);
          var nextPair = this._unusedEffectPairs[index];
          this._unusedEffectPairs.splice(index, 1);
          this._usedEffectPairs.push(nextPair);
          this._effectPair = Slideshow.Options.effectPairs[nextPair];
        }
        else {
          throw('Could not determine next random effectPair');
        }
      }
      var currZ = 1;
      if (this.currentFrame) {
        this.currentFrame.style.zIndex = (this.currentFrame.style && this.currentFrame.style.zIndex)
          ? this.currentFrame.style.zIndex : '1';
        currZ = parseInt(this.currentFrame.style.zIndex);
        this._effectPair['hide'](this.currentFrame, this.options.hideOptions);
      }
      newFrame.style.zIndex = '' + (++currZ);
      this._effectPair['show'](newFrame, this.options.showOptions);
      this.currentFrame = newFrame;

      if (this.options.afterChange) {
        this.options.afterChange(this, currentIndex);
      }

      if (! this.isPaused) {
        setTimeout(this._nextFrame.bind(this), this.options.delay);
      }
    }
  },
  pause: function () {
    this.isPaused = true;
  },
  play: function () {
    this.isPaused = false;
    this._isRandom = this.options.randomize;
    this._nextFrame();
  },
  goBack: function () {
    this._isRandom = false;
    this.pause();
    if (this._usedFrames.length > 1) {
      this._unusedFrames.unshift(this._usedFrames.pop());
      this._unusedFrames.unshift(this._usedFrames.pop());
    }
    else if (this.options.repeat) {
      this._unusedFrames.unshift(this._usedFrames.pop());
      this._unusedFrames.unshift(this._unusedFrames.pop());
    }
    this._changeFrame();
  },
  goForward: function () {
    this._isRandom = false;
    this.pause();
    this._changeFrame();
  },
  goTo: function (index) {
    this._isRandom = false;
    this.pause();
    var newFrame = null;
    
    if (this.options.frames) {
	    newFrame = this.options.frames[index];
    }
    else {
	    newFrame =  $A(this.element.childNodes)[index];
    }
    
    if ( this.currentFrame == newFrame )
    	return;

    if (newFrame) {
      if (this.options.beforeChange) {
        this.options.beforeChange(this,index);
      }    

      var currZ = 1;
      if (this.currentFrame) {
        this.currentFrame.style.zIndex = (this.currentFrame.style && this.currentFrame.style.zIndex)
          ? this.currentFrame.style.zIndex : '1';
        currZ = parseInt(this.currentFrame.style.zIndex);
        this._effectPair['hide'](this.currentFrame, this.options.hideOptions);
      }
      newFrame.style.zIndex = '' + (++currZ);
      this._effectPair['show'](newFrame, this.options.showOptions);
      this.currentFrame = newFrame;

      if (this.options.afterChange) {
        this.options.afterChange(this,index);
      }

      if (! this.isPaused) {
        setTimeout(this._nextFrame.bind(this), this.options.delay);
      }
    }    
  },
  repeat: function () {
    this.options.repeat = true;
    if (this.isDone) {
      this.isDone = false;
      this._nextFrame();
    }
  },
  stopRepeating: function () {
    this.options.repeat = false;
  },
  addFrames: function(html) {
    var temp = document.createElement('DIV');
    temp.innerHTML = html;
    Element.cleanWhitespace(temp);
    var newChildren = temp.childNodes.length;
    for (var i=0; i<newChildren; i++) {
      var addedFrame = temp.childNodes[i];
      Element.hide(addedFrame);
      this.element.appendChild(addedFrame);
      this._unusedFrames.push(addedFrame);
    }
  }
} );

Ajax.Slideshow = Class.create();
Object.extend(Object.extend(Ajax.Slideshow.prototype, Effect.Slideshow.prototype), {
  initialize: function (element, url, options) {
    this.element    = $(element);
    this.url        = url;
    this._shared_initialize(options);
    this._doAjax    = true;
    if (this.options.beforeChange) {
      this._oldBeforeChange = this.options.beforeChange;
      this.options.beforeChange = function () { this._oldBeforeChange(this); this._requestFrames(); }.bind(this);
    }
    else {
      this.options.beforeChange = this._requestFrames.bind(this);
    }
  },
  _requestFrames: function () {
    if (this._doAjax && this._unusedFrames.length <= this.options.minFrames) {
      new Ajax.Request(this.url, { method: 'get', onComplete: this._addFrames.bindAsEventListener(this) });
    }
  },
  _addFrames: function (request) {
    if (request.responseText) {
      this.addFrames(request.responseText);
      if (this.options.afterRequest) {
        this.options.afterRequest(this);
      }
      if (this.isDone) {
        this.isDone = false;
        this._nextFrame();
      }
    }
    else {
      // nothing returned means no more images to load, so stop trying
      this.stopRequesting();
    }
  },
  stopRequesting: function () {
    this.options.beforeChange = this._oldBeforeChange || null;
  },
  changeUrl: function (url) {
    this.url = url;
  }
} );

Slideshow.Local = Class.create();
Object.extend(Object.extend(Slideshow.Local.prototype, Effect.Slideshow.prototype), {
  initialize: function (element, frames, options) {
    this.element    = $(element);
    this._spareFrames   = frames;
    this._shared_initialize(options);
    if (this.options.beforeChange) {
      this._oldBeforeChange = this.options.beforeChange;
      this.options.beforeChange = function () { this._oldBeforeChange(this); this._addFrames(); }.bind(this);
    }
    else {
      this.options.beforeChange = this._addFrames.bind(this);
    }
  },
  _addFrames: function () {
    if (this._unusedFrames.length <= this.options.minFrames && this._spareFrames.length) {
      var newFrame = this._spareFrames.shift();
      if (newFrame.indexOf('<') == -1) {
        var img = document.createElement('IMG');
        img.src = newFrame;
        Element.hide(img);
        this.element.appendChild(img);
        this._unusedFrames.push(img);
      }
      else {
        this.addFrames(newFrame);
      }
    }
    else {
      this.options.beforeChange = this._oldBeforeChange || null;
    }
  }
} );


var SlideshowX = {};
SlideshowX.Options = {
  effectPairs: {
    appear: {
      show:   function (element, options) {
        new Effect.Appear(element, options);
      },
      hide:    function (element, options) {
        new Effect.Fade(element, options);
      }
    },
    grow: {
      show:   function (element, options) {
         Effect.Grow(element, options);
      },
      hide:    function (element, options) {
         Effect.Shrink(element, options);
      }
    },
    blind: {
      show:   function (element, options) {
        new Effect.BlindDown(element, options);
      },
      hide:    function (element, options) {
        new Effect.BlindUp(element, options);
      }
    },
    slide: {
      show:   function (element, options) {
        new Effect.SlideDown(element, options);
      },
      hide:    function (element, options) {
        new Effect.SlideUp(element, options);
      }
    },
    simple: {
      show:   function (element, options) {
        Element.show(element);
      },
      hide:    function (element, options) {
        Element.hide(element);
      }
    }
  },
  defaults: {
    minFrames:      2,
    delay:          5,
    randomize:      false,
    repeat:         false,
    effectPair:     'appear',
    showEffect:     null,
    showOptions:    {},
    hideEffect:     null,
    hideOptions:    {},
    beforeChange:   null,
    afterChange:    null,
    startPaused:    false,
    frames: 		null
  }
};

Effect.SlideshowX = Class.create();
Object.extend(Object.extend(Effect.SlideshowX.prototype, Effect.Base.prototype), {
  initialize: function (element, options) {
    this.element = $(element);
    this._shared_initialize(options);
  },
  _shared_initialize: function (options) {
    Element.cleanWhitespace(this.element);

    this.options = SlideshowX.Options.defaults;
    Object.extend(this.options, options);
    if (this.options.showEffect && this.options.hideEffect) {
      this._effectPair = {
        show:   this.options.showEffect,
        hide:   this.options.hideEffect
      };
    }
    else if (this.options.effectPair == 'random') {
      this._usedEffectPairs    = [];
      this._unusedEffectPairs  = [];
      for (type in SlideshowX.Options.effectPairs) {
        this._unusedEffectPairs.push(type);
      }
    }
    else if (SlideshowX.Options.effectPairs[this.options.effectPair]) {
      this._effectPair = SlideshowX.Options.effectPairs[this.options.effectPair];
    }
    else {
      throw('Slideshow requires a valid effectPair or showEffect AND hideEffect to work');
    }
    this.options.delay = parseInt(this.options.delay * 1000);
    this._isRandom = this.options.randomize;

    var showTime = parseInt((this.options.showOptions.duration || 1.0) * 1000);
    var hideTime = parseInt((this.options.hideOptions.duration || 1.0) * 1000);
    if (showTime > hideTime) {
      this.options.delay += showTime;
    }
    else {
      this.options.delay += hideTime;
    }

    this._usedFrames   = [];
    
    if (this.options.frames) {
	    this._unusedFrames = $A(this.options.frames);
	    this._allFrames = this.options.frames;
    }
    else {
	    this._unusedFrames = $A(this.element.childNodes);
	    this._allFrames = $A(this.element.childNodes);
    }
    
    this._unusedFrames.each( function (el) { Element.hide(el); } );

    this.isPaused = this.options.startPaused || false;
    this.isDone   = false;
    
    this._nextFrame();
  },
  _getNextFrame: function () {
    if (! this._unusedFrames.length) {
      if (this.options.repeat && this._usedFrames.length) {
        this._unusedFrames = this._usedFrames;
        this._usedFrames   = [this._unusedFrames.pop()];
      }
      else {
        this.isDone = true;
        return null;
      }
    }

    var nextFrame = null;
    var numUnused = this._unusedFrames.length;
    if (this._isRandom && numUnused > 1) {
      var index = Math.floor(Math.random()*numUnused);
      nextFrame = this._unusedFrames[index];
      this._unusedFrames.splice(index, 1);
    }
    else {
      nextFrame = this._unusedFrames.shift();
    }
    this._usedFrames.push(nextFrame);

    return nextFrame;
  },
  _nextFrame: function () {
    if (! this.isPaused) {
      this._changeFrame();
    }
  },
  _changeFrame: function () {
    var newFrame = this._getNextFrame();
    if (newFrame) {
    
      var currentIndex = this._allFrames.indexOf(newFrame);

      if (this.options.beforeChange) {
        this.options.beforeChange(this, currentIndex);
      }

      if (this.options.effectPair == 'random') {
        if (! this._unusedEffectPairs.length) {
          this._unusedEffectPairs  = this._usedEffectPairs;
          this._usedEffectPairs    = [ this._unusedEffectPairs.pop() ];
        }
        if (this._unusedEffectPairs.length) {
          var index = Math.floor(Math.random()*this._unusedEffectPairs.length);
          var nextPair = this._unusedEffectPairs[index];
          this._unusedEffectPairs.splice(index, 1);
          this._usedEffectPairs.push(nextPair);
          this._effectPair = SlideshowX.Options.effectPairs[nextPair];
        }
        else {
          throw('Could not determine next random effectPair');
        }
      }
      var currZ = 1;
      if (this.currentFrame) {
        this.currentFrame.style.zIndex = (this.currentFrame.style && this.currentFrame.style.zIndex)
          ? this.currentFrame.style.zIndex : '1';
        currZ = parseInt(this.currentFrame.style.zIndex);
        this._effectPair['hide'](this.currentFrame, this.options.hideOptions);
      }
      newFrame.style.zIndex = '' + (++currZ);
      this._effectPair['show'](newFrame, this.options.showOptions);
      this.currentFrame = newFrame;

      if (this.options.afterChange) {
        this.options.afterChange(this, currentIndex);
      }

      if (! this.isPaused) {
        setTimeout(this._nextFrame.bind(this), this.options.delay);
      }
    }
  },
  pause: function () {
    this.isPaused = true;
  },
  play: function () {
    this.isPaused = false;
    this._isRandom = this.options.randomize;
    this._nextFrame();
  },
  goBack: function () {
    this._isRandom = false;
    this.pause();
    if (this._usedFrames.length > 1) {
      this._unusedFrames.unshift(this._usedFrames.pop());
      this._unusedFrames.unshift(this._usedFrames.pop());
    }
    else if (this.options.repeat) {
      this._unusedFrames.unshift(this._usedFrames.pop());
      this._unusedFrames.unshift(this._unusedFrames.pop());
    }
    this._changeFrame();
  },
  goForward: function () {
    this._isRandom = false;
    this.pause();
    this._changeFrame();
  },
  goTo: function (index) {
    this._isRandom = false;
    this.pause();
    var newFrame = null;
    
    if (this.options.frames) {
	    newFrame = this.options.frames[index];
    }
    else {
	    newFrame =  $A(this.element.childNodes)[index];
    }
    
    if ( this.currentFrame == newFrame )
    	return;

    if (newFrame) {
      if (this.options.beforeChange) {
        this.options.beforeChange(this,index);
      }    

      var currZ = 1;
      if (this.currentFrame) {
        this.currentFrame.style.zIndex = (this.currentFrame.style && this.currentFrame.style.zIndex)
          ? this.currentFrame.style.zIndex : '1';
        currZ = parseInt(this.currentFrame.style.zIndex);
        this._effectPair['hide'](this.currentFrame, this.options.hideOptions);
      }
      newFrame.style.zIndex = '' + (++currZ);
      this._effectPair['show'](newFrame, this.options.showOptions);
      this.currentFrame = newFrame;

      if (this.options.afterChange) {
        this.options.afterChange(this,index);
      }

      if (! this.isPaused) {
        setTimeout(this._nextFrame.bind(this), this.options.delay);
      }
    }    
  },
  repeat: function () {
    this.options.repeat = true;
    if (this.isDone) {
      this.isDone = false;
      this._nextFrame();
    }
  },
  stopRepeating: function () {
    this.options.repeat = false;
  },
  addFrames: function(html) {
    var temp = document.createElement('DIV');
    temp.innerHTML = html;
    Element.cleanWhitespace(temp);
    var newChildren = temp.childNodes.length;
    for (var i=0; i<newChildren; i++) {
      var addedFrame = temp.childNodes[i];
      Element.hide(addedFrame);
      this.element.appendChild(addedFrame);
      this._unusedFrames.push(addedFrame);
    }
  }
} );

Ajax.SlideshowX = Class.create();
Object.extend(Object.extend(Ajax.SlideshowX.prototype, Effect.SlideshowX.prototype), {
  initialize: function (element, url, options) {
    this.element    = $(element);
    this.url        = url;
    this._shared_initialize(options);
    this._doAjax    = true;
    if (this.options.beforeChange) {
      this._oldBeforeChange = this.options.beforeChange;
      this.options.beforeChange = function () { this._oldBeforeChange(this); this._requestFrames(); }.bind(this);
    }
    else {
      this.options.beforeChange = this._requestFrames.bind(this);
    }
  },
  _requestFrames: function () {
    if (this._doAjax && this._unusedFrames.length <= this.options.minFrames) {
      new Ajax.Request(this.url, { method: 'get', onComplete: this._addFrames.bindAsEventListener(this) });
    }
  },
  _addFrames: function (request) {
    if (request.responseText) {
      this.addFrames(request.responseText);
      if (this.options.afterRequest) {
        this.options.afterRequest(this);
      }
      if (this.isDone) {
        this.isDone = false;
        this._nextFrame();
      }
    }
    else {
      // nothing returned means no more images to load, so stop trying
      this.stopRequesting();
    }
  },
  stopRequesting: function () {
    this.options.beforeChange = this._oldBeforeChange || null;
  },
  changeUrl: function (url) {
    this.url = url;
  }
} );

SlideshowX.Local = Class.create();
Object.extend(Object.extend(SlideshowX.Local.prototype, Effect.SlideshowX.prototype), {
  initialize: function (element, frames, options) {
    this.element    = $(element);
    this._spareFrames   = frames;
    this._shared_initialize(options);
    if (this.options.beforeChange) {
      this._oldBeforeChange = this.options.beforeChange;
      this.options.beforeChange = function () { this._oldBeforeChange(this); this._addFrames(); }.bind(this);
    }
    else {
      this.options.beforeChange = this._addFrames.bind(this);
    }
  },
  _addFrames: function () {
    if (this._unusedFrames.length <= this.options.minFrames && this._spareFrames.length) {
      var newFrame = this._spareFrames.shift();
      if (newFrame.indexOf('<') == -1) {
        var img = document.createElement('IMG');
        img.src = newFrame;
        Element.hide(img);
        this.element.appendChild(img);
        this._unusedFrames.push(img);
      }
      else {
        this.addFrames(newFrame);
      }
    }
    else {
      this.options.beforeChange = this._oldBeforeChange || null;
    }
  }
} );


/*
  Fun??es utilit?rias para recupera??o dos slides e atualiza??o do navegador
*/

	function atualizaNavegador(slideshow, indiceFrameSelecionado) {
		var idElemento = slideshow.element.id;
		var control = $(idElemento+'_control_'+ indiceFrameSelecionado);
		var classControls = idElemento + '_control';
		var controles = document.getElementsByClassName(classControls);
		var off = {background: '#BFC1B9', color: 'white'};
		var on  = {background: '#91998E', color: 'white'};
		controles.each( function (el) { 
							if (el == control) {
								Element.setStyle(el, on);
							} else {
								Element.setStyle(el, off);
							}
		                } ); 
	}
	
	function obtemChamadasDestaque(region){ 
		var divs = $A($(region).getElementsByTagName('div'));
		var divsChamadas = divs.findAll( function(div){
												var className = new String(Element.classNames(div));
												var prefix = className.substring(0,10);
												return (prefix == 'chDestaque') ||  (prefix == 'chPrincipa') ;
										});
		return divsChamadas;
	}

	function obtemFrames(region){ 
		var divs = $A($(region).getElementsByTagName('div'));
		var divsChamadas = divs.findAll( function(div){
												var className = new String(Element.classNames(div));
												var prefix = className.substring(0,10);
												return (prefix == 'chDestaque') ||  (prefix == 'chPrincipa') ;
										});
		
		// Se existem menos de 4 chamadas cadastradas, apresenta a publicidade no frame 4 da TV
		if (divsChamadas.length < 4) {
			divsChamadas[3] = $('tvFramePublicidade');
		}
		
		return divsChamadas;
	}
	