//Needs UtilityService.js and scriptaculous and make sure to initialize the global variable baseURL to a valid path for ajax requests

var SliderHandler=Class.create(PanelHandler,
{
   initialize:function($super,containerId,parentHandler,imageSourceList)
   {
       $super(containerId,parentHandler);

       this.indexCurrentImage=-1;       
       //this.initEvents();
       this.myImages=null;
       this.myImages=this.getImages(imageSourceList);
       this.numberOfLoadedImages=0;
   },
   
   getImages:function(imageSourceList)
   {
       if(this.myImages!=null)
           return this.myImages;
       else
       {//create an image slide object for each given image source
           var imagesHash=new Hash();
           for(var i=0;i<imageSourceList.size();i++)
           {
               var myImage=new ImageForSliding(i,imageSourceList[i],this);
               //the image element created is hidden by default
               imagesHash.set(i,myImage);
           }
           return imagesHash;
       }
   },
    
   startSlide:function()
   {
       if(this.myImages.size()>0)
       {
           var initialIndex=0;
           this.indexCurrentImage=initialIndex;
           var startingImage=this.myImages.get(this.indexCurrentImage);
           if(!startingImage.isReady())
           {
               startingImage.startLoading();
           }
       }
       else
       {
           alert("No images to be displayed?");
       }
   },
       
   getNextIndex:function(currentIndex)
   {
       var nextIndex=0;
       var max=this.myImages.keys().size()-1;
       var min=0;
       
       if(currentIndex >= max)
       {
           //Back to the beginning
           nextIndex=min;
       }
       else if(currentIndex<min)
       {
           //To the end
           nextIndex=max;
       }
       else
       {
           nextIndex=currentIndex+1;
       }
       return nextIndex;
   },

   showImage:function(imageForSliding)
   {
       //after all the effects are displayed, update current index
       //effect queues are not working so for now lets make linked effects
       var imageElement=imageForSliding.getImageElement();       
      //imageElement.absolutize();

      Effect.Appear
      (
         imageElement,
         {
             from:0.1,
             queue:{position:"end",scope:"slideEffect1"}
         }
      );
      Effect.Fade
      (
         imageElement,
         {
           delay:2,
           //to:0.5,
           queue:{position:"end",scope:"slideEffect1"}
           ,afterFinish:function()
           {
               imageElement.hide();
               imageElement.setStyle({opacity: 1});
               this.indexCurrentImage=this.getNextIndex(this.indexCurrentImage);
               var nextImage=this.getImages(null).get(this.indexCurrentImage);

               if(!nextImage.hasAtttemptedToLoadAlready())
               {
                   nextImage.startLoading();
               }
               else if(nextImage.isReady())
               {
                   this.showImage(nextImage,imageElement);
               }
           }.bind(this,imageElement)}
      );

   },
   
   getIndexCurrentImage:function()
   {
       return this.indexCurrentImage;
   },

   setNumberOfLoadedImages:function(numberOfLoadedImages)
   {
       this.numberOfLoadedImages=numberOfLoadedImages;
   },

   getNumberOfLoadedImages:function()
   {
       return this.numberOfLoadedImages;
   }
});

var ImageForSliding=Class.create({
   
   initialize:function(index,source,parentHandler)
   {
       this.parentSliderHandler=parentHandler;
       this.imageElement=new Element("img");
       this.imageElement.identify();
       this.imageElement.hide();
       this.mySource=source;
       this.isLoaded=false;
       this.hasAttemptedToLoad=false;
       this.parentSliderHandler.getEContainer().insert(this.imageElement);
       
       this.index=index;
       this.loadNextAfterCompleted=false;
   },
   
   isReady:function()
   {
       return this.isLoaded;
   },
   
   initEvents:function()
   {
       this.imageElement.stopObserving("load");
       this.imageElement.observe("load",
         function()
         {
            //flag to consider only real loadings and not when src=""
            if(this.hasAttemptedToLoad && !this.isReady())
            {                
                //Image is really loaded
                this.isLoaded=true;
                this.parentSliderHandler.setNumberOfLoadedImages(this.parentSliderHandler.getNumberOfLoadedImages()+1);

                if(this.imageElement.getHeight()>0) this.imageElement.writeAttribute('height',this.imageElement.getHeight());//CRZF-196
                if(this.imageElement.getWidth()>0) this.imageElement.writeAttribute('width',this.imageElement.getWidth());//CRZF-196

                //it is your turn to be shown!               
                if(this.index == this.parentSliderHandler.getIndexCurrentImage())
                {//this happens ONLY when the slidePanel was waiting for this image to load in order to show it
                    this.parentSliderHandler.showImage(this);
                }
                //load next
                if(this.parentSliderHandler.getNumberOfLoadedImages()<this.parentSliderHandler.getImages().keys().size())
                {   //if there are still images that need to be loaded
                    var indexTemp=this.parentSliderHandler.getIndexCurrentImage();
                    var indexNextImageToBeLoaded=indexTemp;
                    var nextImageToBeLoaded=this.parentSliderHandler.getImages().get(indexNextImageToBeLoaded);

                    while(nextImageToBeLoaded.isReady())
                    {//if the next has already been loaded, then try the next and so on
                        indexTemp=indexNextImageToBeLoaded;
                        indexNextImageToBeLoaded=this.parentSliderHandler.getNextIndex(indexTemp);
                        nextImageToBeLoaded=this.parentSliderHandler.getImages().get(indexNextImageToBeLoaded);
                    }
                    //alert("next image to be loaded is "+nextImageToBeLoaded.index);
                    //check: if there's still one that needs to be loaded
                    nextImageToBeLoaded.startLoading();
                }
            }
         }.bind(this)
       );
   },
   
   startLoading:function()
   {     
       this.initEvents();
       this.imageElement.writeAttribute("src",this.mySource);
       this.hasAttemptedToLoad=true;
   },

   getImageElement:function()
   {
       return this.imageElement;
   },

   hasAtttemptedToLoadAlready:function()
   {return this.hasAttemptedToLoad;}
   
});

var ListAnimator=Class.create(PanelHandler,{
   initialize:function($super,containerId,parentHandler)
   {
       $super(containerId,parentHandler);

       this.myElements=null;
       this.myElements=this.getElements();

       this.myElements.each
       (
          function(myElement)
          {
             //this.animateElement(myElement,"teaserScope");
             myElement.setStyle({opacity:0.6});
          }.bind(this)
       );
   },
   
   getElements:function()
   {
       if(this.myElements==null)
       {
           return this.getEContainer().childElements()
       }
       else
         return this.myElements;  
   },

   initEvents:function()
   {
       this.myElements.each
       (
          function(myElement)
          {
             myElement.observe("mouseover",
               function()
               {
                   //this.animateElement(myElement,'teaserScope'+myElement.identify());
                   new Effect.Opacity(myElement,
                   { //from: 1.0,
                     to: 1.0,
                     duration: 0.3,
                     queue:{position:"end",scope: 'teaserScope'+myElement.identify()}
                   });

               }.bind(this,myElement)
             );

             myElement.observe("mouseout",
               function()
               {
                   //this.animateElement(myElement,'teaserScope'+myElement.identify());
                   new Effect.Opacity(myElement,
                   { //from: 1.0,
                     to: 0.6,
                     duration: 0.5,
                     queue:{position:"end",scope: 'teaserScope'+myElement.identify()}
                   });
               }.bind(this,myElement)
             );
          }.bind(this)
       );
   },

   animateElement:function(element,effectScope)
   {
       /*
       new Effect.Move
       ( element,         
         {
           queue:{position:"end",scope: effectScope},
           duration:0.3,
           y:20
         }
        );
       new Effect.Move
       ( element,         
         {
           queue:{position:"end",scope:effectScope},
           duration:0.3,
           y:-20
         }
        );
            */

   }
});

var TeaserListAnimator=Class.create(ListAnimator,{
   initialize:function($super,containerId,parentHandler)
   {
       $super(containerId,parentHandler);
   },

   //overriding this method
   getElements:function()
   {
       if(this.myElements==null)
       {
           var listElements=this.getEContainer().childElements()
           var effectiveElements=new Hash();
           for(var i=0;i<listElements.size();i++)
           {
               var temp=listElements[i];
               var arrayTemp=temp.select("img");
               if(arrayTemp.size()>0)
               {
                   var effElement=arrayTemp.first();
                   effectiveElements.set(effElement.identify(),effElement);
               }
           }
           return effectiveElements.values();
       }
       else
         return this.myElements;
   }
});

//not used
var LogoAnimator=Class.create(PanelHandler,{
   initialize:function($super,containerId,parentHandler)
   {
       $super(containerId,parentHandler);
   },

   animateElement:function()
   {
       var element=this.getEContainer();
          element.hide();
          Effect.Grow
           ( element,
             {
               //queue:{position:"end",scope: "logoEffect"}
               duration:1.3,
               direction:'center',
               afterSetup:function()
               {
                   element.show();
               }.bind(this,element)
             }
           );
   }
});

//requires SlideShowHandler on slideShowHandler.js
var WhatsNewPanelHandler=Class.create(PanelHandler,{

   initialize:function($super,containerId,sourceList,parentHandler)
   {
       $super(containerId,parentHandler);
       this.getEContainer().hide();//not displayed by default unless you explicitly call .show();

       this.vSELECTOR_CLOSE_BUTTON="closeButton";
       var slideShowId=UtilityService.prototype.getFirstMatching(this.getEContainer(),'class','whatsNewSlideShow').identify();
       this.slideShow=new SlideShowHandler(slideShowId,sourceList,{parentHandler:this, delay:3.5});
       this.initEvents();
   },
  
   getSlideShow:function(){return this.slideShow;},
   getECloseButton:function(){return UtilityService.prototype.getFirstMatching(this.getEContainer(),"class",this.vSELECTOR_CLOSE_BUTTON);},

   initEvents:function()
   {
       this.getECloseButton().observe('click',
       function(){
           this.hide();
           this.saveInfo();
       }.bind(this));
   },

   show:function()
   {
       if($('outer'))
       {
           this._oldPosition=$('outer').getStyle('position');
           $('outer').setStyle({position:'static'});//NEEDED thanks to our besty IE
       }

       Effect.Appear(this.getOverlay(),
       {
           duration:0.5,
           to:0.8//to preserve overlays opacity
       });//this.getOverlay().show();
       Effect.Appear(this.getEContainer());//this.getEContainer().show();

       if(this.getSlideShow().hasStarted())
           this.getSlideShow().resumeSlideShow();
       else
           this.getSlideShow().startSlideShow();
   },
   hide:function()
   {
       Effect.Fade(this.getOverlay());//this.getOverlay().hide();
       Effect.Fade(this.getEContainer(),
       {
           duration:0.5,
           afterFinish:function()
           {
              if($('outer'))$('outer').setStyle({position:this._oldPosition});//NEEDED thanks to IE
           }.bind(this)
       });//this.getEContainer().hide();

       if(this.getSlideShow().hasStarted())
           this.getSlideShow().pauseSlideShow();

       //if($('outer'))$('outer').setStyle({position:this._oldPosition});//NEEDED thanks to IE

   },

   saveInfo:function()
   {
       var eAcceptSpamSection=UtilityService.prototype.getFirstMatching(this.getEContainer(),"class","acceptSpamSection");
       if(eAcceptSpamSection)
       {
           if(UtilityService.prototype.getFirstMatching(eAcceptSpamSection,'name','acceptSpam_original').getValue()!=UtilityService.prototype.getFirstMatching(eAcceptSpamSection,'name','acceptSpam').getValue())
             $('acceptSpamFormId').request({method:"post"});//it's necessary to specify the method
       }
   },

   getOverlay:function(){//TODO: Thinking that this should be generalized for panels that always need a modal-like background
       var overlayBackgroundId='overlayBackgroundId';
       var overlayBackground=$(overlayBackgroundId);
       if(!overlayBackground)
       {
          var style="display:none;";
          //Note! This is ok, don't modify it!
          if(UtilityService.prototype.isIE()) style=style+"width: 200%;\
            height: 200%;\
            min-height: 100%;\
            min-width: 100%;\
            background-color: #000;\
            filter: alpha(opacity=80);\
            -moz-opacity: 0.8;\
            opacity: 0.8;\
            z-index: 10;\
            position: absolute;\
            top:expression(eval(document.compatMode && document.compatMode=='CSS1Compat') ? documentElement.scrollTop +(documentElement.clientHeight-this.clientHeight) - 1: document.body.scrollTop+(document.body.clientHeight-this.clientHeight) - 1);\
            left:expression(eval(document.compatMode && document.compatMode=='CSS1Compat') ? documentElement.scrollLeft+(documentElement.clientWidth-this.clientWidth) - 1: document.body.scrollLeft+(document.body.clientWidth-this.clientWidth) - 1);";
           else style=style+"position: fixed;width: 200%;height: 200%;top: -50%;left: -50%;min-height: 100%;background-color: #000;filter: alpha(opacity=80);-moz-opacity: 0.8;opacity: 0.8;z-index: 10;";

          //new Insertion.Before($(document.body), '<div id="'+overlayBackgroundId+'" style="'+style+'"/>');
          overlayBackground=new Element("div",{id:overlayBackgroundId, style:style});
          $(document.body).insert(overlayBackground);

          overlayBackground=$(overlayBackgroundId);
       }
       return overlayBackground;
   }
});
