/*    5/11/2010
    PikaChoose
  Jquery plugin for photo galleries
    Copyright (C) 2010 Jeremy Fry

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

(function (jQuery) {
  jQuery.fn.PikaChoose = function (user_options) {
    var defaults = {
      show_captions: false,
      auto_play: true,
      show_prev_next: true,
      slide_speed: 5000,
      thumb_width: 90,
      thumb_height: 31,
      buttons_text: { play: "", stop: "", previous: "Previous", next: "Next" },
      delay_caption: true,
      user_thumbs: true,
      transition:[-1],
      IESafe: true
    };
        
    return jQuery(this).each(
      function() 
      {
        function CreateThumbnail()
        {
          var image = jQuery(this);
          var aParent = jQuery(this).parent('a');
          if(aParent.length == 0){ aParent = jQuery(this); }
          aParent.hide();
          jQuery(this).attr('pikaLink', aParent.attr('href'));
          //pull it out of the a tag
          image = jQuery(this).clone(true).insertAfter(aParent);
          jQuery(this).removeClass('pika_first');
          //wait for load to remove previous or ie will never see the page loaded
          jQuery(this).bind("load",function(){ aParent.remove(); });
          jQuery('<img />').load(function()
          {
            var w = image.width();
            var h = image.height();
            // if(w===0){w = image.attr("width");}
            // if(h===0){h = image.attr("height");}
            // //grab a ratio for image to user defined settings
            // var rw = options.thumb_width/w;
            // var rh = options.thumb_height/h;
            // 
            // //determine which has the smallest ratio (thus needing
            // //to be the side we use to scale so our whole thumb is filled)
            // var ratio;
            // if(rw<rh){
            //   //we'll use ratio later to scale and not distort
            //   ratio = rh;
            //   var left = ((w*ratio-options.thumb_width)/2)*-1;
            //   left = Math.round(left);
            //   //set images left offset to match
            //   image.css({left:left});
            // }else{
            //   ratio = rw;
            //   var top = 0;
            //   image.css({top:top});
            // }
            // //use those ratios to calculate scale
            // var width = Math.round(w*ratio);
            // var height = Math.round(h*ratio);
            image.css("position","relative");
            image.width(w).height(h);
            var imgcss={
              width: w,
              height: h
            };
            image.css(imgcss);          
            image.hover(
              function(){jQuery(this).fadeTo(250,0.4);},
              function(){if(!jQuery(this).hasClass("pika_selected")){jQuery(this).fadeTo(250,1);}}
            );
            if(ulist.children('li').find('img:last').index(image)==0){
              image.fadeTo(250,0.4);  
            }else{
              image.fadeTo(250,1);  
            }
            jQuery(this).show();
          }).attr('src',image.attr('src'));
          //reset images to the clones
          
          images = ulist.children('li').find('img:last');
        }
        //bring in options
        var tranStep = 0;
        var options = jQuery.extend(defaults, user_options);
        var images = jQuery(this).children('li').find('img');
        images.hide();
        //save our list for future ref
        var ulist = jQuery(this);
        ulist.children("li:last").children("img").addClass("pika_last");
        images.each(CreateThumbnail);
        //start building structure
        jQuery(this).before("<div class='pika_main'></div>");
        // houses eveything about the UL
        var main_div = jQuery(this).prev(".pika_main");
        
        //add in slideshow elements when appropriate
        main_div.append("<div class='pika_play'></div>");
        var play_div = jQuery(this).prev(".pika_main").children(".pika_play");
        play_div.html("<a class='pika_play_button'>" + options.buttons_text.play + "</a><a class='pika_stop_button'>" + options.buttons_text.stop + "</a>");
        //play_div.fadeOut(1);
        var play_anchor = play_div.children('a:first');
        var stop_anchor = play_div.children('a:last');
        //this div is used to make image and caption fade together
        main_div.append("<div class='pika_subdiv'></div>");
        var sub_div = main_div.children(".pika_subdiv");
        //the main image we'll be using to load
        var firstImage = ulist.find("img:first");
        if(options.user_thumbs)
        {   
          firstImage = firstImage.attr('ref');
        }else
        {
          firstImage = firstImage.attr('src');
        }
        
        
        sub_div.append("<img class='pika_main_img' src='"+firstImage+"' />");
        sub_div.append("<div class='pika_animationDivs'>");
        var ani_divs = sub_div.find(".pika_animationDivs");
        ani_divs.css({'position':'absolute','width':'100%','height':'100%'});

        var y = 0;
        var x = 0;
        for(var t = 0; t<25;t++)
        {
          var a = '<div col="'+y+'" row="'+x+'"></div>';
          ani_divs.append(a);
          y++
          if(y == 5)
          {
            x++;
            y=0;
          }
        }
        ani_divs.children(':last').addClass("pikaLastAni");
        var main_img = sub_div.children("img");
        //build custom overlays. These will use navigation div
        sub_div.append("<div class='pika_prev_hover'></div><div class='pika_next_hover'></div>");
        var prevHover = sub_div.find('.pika_prev_hover');
        var nextHover = sub_div.find('.pika_next_hover');
        prevHover.hide();
        nextHover.hide();
        //create the caption div when appropriate
        if(options.show_captions){
          main_div.append("<div class='pika_caption'></div>");
          var caption_div = main_div.children(".pika_caption");
        }
        
        //navigation div ALWAYS gets created, its refrenced a lot       
        ulist.after("<div class='pika_navigation'></div>");
        var navigation_div = jQuery(this).next(".pika_navigation");
        //fill in sub elements
        navigation_div.append("<a>" + options.buttons_text.previous + "</a> :: <a>" + options.buttons_text.next + "</a>");
        var previous_image_anchor = navigation_div.children('a:first');
        var next_image_anchor = navigation_div.children('a:last');
        
        //hide the navigation if the user doesn't want it
        if(!options.show_prev_next){
          navigation_div.css("display","none");
        }
        
        //playing triggers the loop for the slideshow
        var playing = options.auto_play;
        var animating = false;
        main_img.wrap("<a></a>");
        var main_link = main_img.parent("a");
        
      function activate()
      {
        //sets the intial phase for everything
        //image_click is controls the fading
        images.bind("click",image_click);
        
        //hiding refrence to slide elements if slide is disabled
        
        if(options.auto_play){
          playing = true;
          play_anchor.hide();
          stop_anchor.show();
        }else{
          play_anchor.show();
          stop_anchor.hide();
        }
      
        
        ulist.children("li:last").children("img").addClass("pika_last");
        ulist.children("li:first").children("img").addClass("pika_first");
        ulist.children("li").each(function(){ jQuery(this).children("span").hide(); });
        //css for the list
        var divcss = {
          // width: options.thumb_width+"px",
          // height: options.thumb_height+"px",
          "list-style": "none",
          overflow: "hidden"
        };
        var licss = {
          "list-style": "none",
          overflow: "hidden"
        };
        images.each(function(){
          jQuery(this).parent('li').css(licss);
          jQuery(this).wrap(document.createElement("div"));
          jQuery(this).parent('div').css(divcss);
        });
        //previous link to go back an image
        previous_image_anchor.bind("click",previous_image);
        prevHover.bind("click",previous_image);
        //ditto for forward, also the item that gets auto clicked for slideshow

        next_image_anchor.bind("click",next_image);
        nextHover.bind("click",next_image); 
        
        //enable mouse tracking for the hover
        sub_div.mousemove(function(e){
          var w = sub_div.width();
          var x = e.pageX - sub_div.offset().left;
            if(x<w*0.3)
            {
              prevHover.fadeIn('fast');
            }else{
              prevHover.fadeOut('fast');
            }
            if(x>w*0.7)
            {
              nextHover.fadeIn('fast'); 
            }else{
              nextHover.fadeOut('fast');  
            }
        });
        sub_div.mouseleave(function(){ prevHover.fadeOut('fast');nextHover.fadeOut('fast'); });
      }//end activate function
      
      function Gapper(ele, aHeight)
      {
        if(ele.attr('row') == 9 && ele.attr('col') == 0)
        {
          //last row, check the gap and fix it!
          var gap = ani_divs.height()-(aHeight*9);
          return gap;
        }
        return aHeight;
      }
      
      
      function AnimateImage(image_source, image_link,how)
      {
        //main_img.hide();
        jQuery('<img />').load(function()
        {
          ani_divs.height(main_img.height()).show();
          ani_divs.children('div').css({'width':'20%','height':'20%','float':'left'});
          var aWidth = ani_divs.children('div:first').width();
          var aHeight = ani_divs.children('div:first').height();
          if(how!="autoFirst"){
            ani_divs.children().each(function()
            {
              //position myself absolutely
              var div = jQuery(this);
              var xOffset = Math.floor(div.parent().width()/5)*div.attr('col');
              var yOffset = Math.floor(div.parent().height()/5)*div.attr('row');
              div.css({
                'background':'url('+image_source+') -'+xOffset+'px -'+yOffset+'px',
                'width':'0px',
                'height':'0px',
                'position':'absolute',
                'top':yOffset+'px',
                'left':xOffset+'px',
                'float':'none'
              });
            });//end ani_divs.children.each
          }

          //decide our transition
          var n = 0;
          if(options.transition[0] == -1)
          { //random
            n = Math.floor(Math.random()*5);
          }else{
            n = options.transition[tranStep];
            tranStep++;
            if(tranStep >= options.transition.length){tranStep=0;}
          }
          if(options.IESafe == true)
          {
            if(jQuery.browser.msie)
            {
              n = 0;
            }
          
          }
          switch(n)
          {
            case 0:
              //full frame fade              
              ani_divs.height(main_img.height()).hide().css({'background':'url('+image_source+') top left no-repeat'});
              ani_divs.children('div').hide();
              ani_divs.fadeIn('slow',function(){
                FinishedAnimating(image_source,image_link);
                
                ani_divs.css({'background':'transparent'});
              });
              break;
            case 1:
              ani_divs.children().hide().each(function(index)
              {  
                //animate out as blocks 
                var delay = index*10;
                jQuery(this).delay(delay).animate({"width":aWidth,"height":aHeight},800,'linear',function()
                {
                  if(jQuery(this).hasClass('pikaLastAni'))
                  {
                    FinishedAnimating(image_source,image_link);
                  }
                });
              });
              break;
            case 2:
              ani_divs.children().hide().each(function(index)
              {
                var delay = jQuery(this).attr('row')*10;
                jQuery(this).css({"width":aWidth}).delay(delay).animate({"height":aHeight},800,'linear',function()
                {
                  if(jQuery(this).hasClass('pikaLastAni'))
                  {
                    FinishedAnimating(image_source,image_link);
                  }
                });
              });
              break;            
            case 3:
              ani_divs.children().hide().each(function(index)
              {
                var delay = jQuery(this).attr('col')*10;
                aHeight = Gapper(jQuery(this), aHeight);
                jQuery(this).css({"height":aHeight}).delay(delay).animate({"width":aWidth},800,'linear',function()
                {
                  if(jQuery(this).hasClass('pikaLastAni'))
                  {
                    FinishedAnimating(image_source,image_link);
                  }
                });
              });
              break;
            case 4:
              ani_divs.children().show().each(function(index)
              {
                var delay = index*Math.floor(Math.random()*5)*10;
                aHeight = Gapper(jQuery(this), aHeight);
                
                if(jQuery(this).hasClass('pikaLastAni'))
                {
                  delay = 800;
                }
                jQuery(this).css({"height":aHeight,"width":aWidth,"opacity":.01}).delay(delay).animate({"opacity":1},800,function()
                {
                  if(jQuery(this).hasClass('pikaLastAni'))
                  {
                    FinishedAnimating(image_source,image_link);
                  }
                });
              });
              break;
          }
        }).attr('src',image_source);//end image preload
      }// end animate images
      
      function FinishedAnimating(image_source,image_link)
      {
        animating = false;
        main_img.attr("src", image_source);
        if(image_link == null){image_link = "#"}
        main_link.attr("href", image_link);
        ani_divs.children().css({"background":"transparent"});
        ani_divs.hide();
        if(playing)
        {
          main_img.animate({opacity:1},options.slide_speed, function()
          {
            //redudency needed here to catch the user clicking on an image during a change.
            if(playing){
              next_image_anchor.trigger("click",["auto"]);
            }
          });
        }
      }
      function image_click(event, how){
          //catch when user clicks on an image Then cancel current slideshow
          if(jQuery(this).hasClass('pika_selected') || animating){ return; }
          if(how!="auto" && how!="autoFirst"){
            animating = true;
            stop_anchor.hide();
            play_anchor.show();
            playing=false;
          
            main_img.stop().dequeue();
            if(options.show_captions)
            {
              caption_div.stop().dequeue();
            }
          }
          //all our image variables
          var image_source = "";
          if(options.user_thumbs)
          {   
            image_source = jQuery(this).attr("ref");
          }else
          {
            image_source = this.src;
          }
          //thumbnail animations
          //old code here, doesn't give proper href to image_link.
          // var image_link = jQuery(this).parent("a").attr("href");
          var image_link = jQuery(this).attr('pikaLink');
          var image_caption = jQuery(this).parent().next("span").html();
          //fade out the old thumb
          images.filter(".pika_selected").fadeTo(250,1); 
          images.filter(".pika_selected").removeClass("pika_selected"); 
          //fade in the new thumb
          jQuery(this).fadeTo(250,0.4);
          jQuery(this).addClass("pika_selected");
          //fade the caption out
          if(options.show_captions)
          {
            if(options.delay_caption)
            {
              caption_div.fadeTo(800,0);
            }
            caption_div.fadeTo(500,0,function(){
              caption_div.html(image_caption);
              caption_div.fadeTo(800,1);
            });
          }
          AnimateImage(image_source, image_link, how);
          
      }//end image_click function
      
      function next_image(event, how){
        pikachoose_div = $(".pikachoose")[0];
                
        if(images.filter(".pika_selected").hasClass("pika_last")){
          //this next line is new (by A. Tokar 5/27/10 ) in order to work on IE 8 in Vista.
          //otherwise vista redirects to the anchor's href
          //TODO: group this with other similar fix somewhere else and delete all href's at the same time.
          images.filter(":first").parents('li').find('a').removeAttr('href');
          
          images.filter(":first").trigger("click",how);
        }else{
          //this next line is new (by A. Tokar 5/27/10 ) in order to work on IE 8 in Vista.
          //otherwise vista redirects to the anchor's href
          //TODO: group this with other similar fix somewhere else and delete all href's at the same time.
          images.filter(".pika_selected").parents('li').next('li').find('a').removeAttr("href");
          
          images.filter(".pika_selected").parents('li').next('li').find('img').trigger("click",how);
        }
      }//end next image function
      
      function previous_image(event, how){
        if(images.filter(".pika_selected").hasClass("pika_first")){
          images.filter(":last").trigger("click",how);
        }else{
          images.filter(".pika_selected").parents('li').prev('li').find('img').trigger("click",how);
        }
      }//end previous image function
      
      function play_button(){
        main_div.hover(
          // function(){play_div.fadeIn(400);},
          // function(){play_div.fadeOut(400);}
        );
        play_anchor.bind("click", function(){
          main_img.stop();
          main_img.dequeue();
          if(options.show_captions)
          {
            caption_div.stop();
            caption_div.dequeue();
          }
          playing = true;
          
          next_image_anchor.trigger("click",["auto"]);
          
          jQuery(this).hide();
          stop_anchor.show();
        });
        stop_anchor.bind("click", function(){
          playing = false;
          jQuery(this).hide();
          play_anchor.show();
        });
      }
      play_button();
      activate();
      ulist.children('li:first').find('img:last').trigger("click",["autoFirst"]);
    });//end return this.each
  }//end build function
  
  //activate applies the appropriate actions to all the different parts of the structure.
  //and loads the sets the first image
})(jQuery);
