//$Id: imageSliderHandler.js 61337 2010-10-06 11:29:09Z johnarne $
//Needs UtilityService.js, panelHandler.js and scriptaculous. Make sure to set the global variable baseURL to a valid path for ajax requests
//Extracted from creaza/script/panels.js in order to allow inheritance since inspera and nordseter also uses it
var ImageSliderHandler=Class.create(PanelHandler,
{
   initialize:function($super,containerId,parentHandler,imageSourceList)
   {       
       $super(containerId,parentHandler);

       this.indexCurrentImage=-1;
       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"}
         }
      );

      if(this.myImages.size()>1)
      {
           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)}
          );
      }



      /*
      Effect.Grow(imageElement,
      {
          //queue:{position:"end",scope:"slideEffect1"},
          duration:0.3,
          afterSetup:function()
          {
              imageElement.show();
          }.bind(this,imageElement)
          ,afterFinish:function()
          {
              new Effect.Scale(imageElement,80,
              {
                  duration:0.2,
                  afterFinish:function()
                  {
                      new Effect.Move(imageElement,
                      {
                        x:30,
                        y:20,
                        duration:0.2,
                        afterFinish:function()
                        {
                          new Effect.Move(imageElement,
                          {
                                x:-30,
                                y:-20,
                                duration:0.2,
                                afterFinish:function()
                                {
                                  new Effect.Scale(imageElement,125,
                                  {
                                      duration:0.2,
                                      afterFinish:function()
                                      {
                                          Effect.Fade(imageElement,
                                          {
                                              //queue:{position:"end",scope:"slideEffect1"},
                                              delay:2,
                                              duration:0.5,
                                              to:0.5,
                                              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)
                                          });
                                      }.bind(this,imageElement)
                                  });
                                }.bind(this,imageElement)
                           });
                        }.bind(this,imageElement)
                     });
                  }.bind(this,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);

                //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;}

});
