/**
 * name:          jquery-foxislide-0.1.js
 * author:        Stefan Benicke - www.opusonline.at
 * version:       0.1
 * last update:   19.08.2009
 * category:      jQuery plugin
 * copyright:     (c) 2009 Stefan Benicke (www.opusonline.at)
 * license:       GNU GPLv3
    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/>.
 * documentation: http://www.opusonline.at/foxitools/foxislide/
 */
(function($) {
	$.fn.foxislide = function(settings) {

		settings = jQuery.extend({
			speed: 'normal',
      title: true,
      callback: function(){}
		}, settings);

		getSize();
    getScroll();
    $(window).scroll(function(){ getScroll(); });
    $(window).resize(function(){ getSize(); });

    var window_width;
    var window_height;
    var scroll_top;
    var scroll_left;
    var is_down = false;
    var is_move = false;
    var moving_element;
    var difference_x = 0;
    var difference_y = 0;
    var images_array = [];
    var counter = 0;

    $(this).each(function(){
      images_array[images_array.length] = this;
      $(this).bind('click', function(){
        open(this);
        return false;
      });

      counter++;
      var foxislide_id = '#foxislide'+counter;
      var this_image = $(this).find('img');
      var this_image_top = this_image.offset().top;
      var this_image_left = this_image.offset().left;
      var this_image_width = this_image.width();
      var this_image_height = this_image.height();
      var foxislide_object = '<div id="foxislide'+counter+'" class="foxislide'+
        '" style="display:none;width:'+this_image_width+'px;height:'+
        this_image_height+'px;top:'+this_image_top+'px;left:'+
        this_image_left+'px;cursor:pointer"><img src="" style="display:none"'+(settings.close_title?' title="'+settings.close_title+'"':'')+' />'+
		'<div class="close">Закрыть</div>';
      if(settings.title && $(this).attr('title')){
        foxislide_object += '<div class="foxislide_title"'+
          ' style="display:none">'+$(this).attr('title')+'</div>';
      }
      foxislide_object += '<span class="foxislide_origin" style="display:none">'+
        (counter-1)+'</span><div class="foxislide_loader" style="display:none;width:'+
        this_image_width+'px;height:'+this_image_height+'px"></div></div>';
      $('body').append(foxislide_object);
      $(this).attr('rel', foxislide_id);
      $(foxislide_id).bind('mousedown', function(event){
        is_down = true;
        is_move = false;
        moving_element = this;
        difference_x = event.pageX-$(this).offset().left;
        difference_y = event.pageY-$(this).offset().top;
        $(this).css({'z-index':getZindex(this), 'cursor':'move'});
        return false;
      }).bind('mousemove', function(event){
        if(is_down){
          is_move = true;
          var new_top = Math.round(event.pageY-difference_y);
          var new_left = Math.round(event.pageX-difference_x);
          if(new_top < 0) new_top = 0;
          if(new_left < 0) new_left = 0;
          $(moving_element).css({'top':new_top, 'left':new_left});
        }
        return false;
      }).bind('mouseup', function(){
        if(is_down){
          is_down = false;
          moving_element = "";
          $(this).css({'cursor':'pointer'});
          if(!is_move) close(this);
        }
      });
    });

    $(document).bind('mousemove', function(event){
      if(is_move){
        var new_top = Math.round(event.pageY-difference_y);
        var new_left = Math.round(event.pageX-difference_x);
        if(new_top < 0) new_top = 0;
        if(new_left < 0) new_left = 0;
        $(moving_element).css({'top':new_top, 'left':new_left});
      }
    });

		$(document).keydown(function(event){
      // 'esc'
      if(event.keyCode == 27){
        $('body').find('div[id^="foxislide"]').each(function(){
          if($(this).css('display') != 'none'){
            close(this);
          }
        });
			}
    });

    function open(element){
      var foxislide_element = $(element).attr('rel');
      var foxislide_image = $(foxislide_element).find('img');

      $(foxislide_element).show().find('.foxislide_loader').show();
      
      var preload_img = new Image();
      preload_img.onload = function(){
        $(element).css('visibility', 'hidden');
        $(foxislide_element).find('.foxislide_loader').hide();
        
        var image_width = preload_img.width;
        var image_height = preload_img.height;
        
        foxislide_image.attr('src', preload_img.src).width($(foxislide_element).width())
          .height($(foxislide_element).height()).show();
        var new_foxislide_top = window_height/2+scroll_top-image_height/2;
        var new_foxislide_left = window_width/2+scroll_left-image_width/2;
        if(new_foxislide_top < 0) new_foxislide_top = 0;
        if(new_foxislide_left < 0) new_foxislide_left = 0;
        foxislide_image.animate({'width':image_width, 'height':image_height,
          'top':new_foxislide_top, 'left':new_foxislide_left}, settings.speed);
        $(foxislide_element).animate({'width':image_width, 'height':image_height,
          'top':new_foxislide_top, 'left':new_foxislide_left}, settings.speed, function(){
          if(settings.title && $(element).attr('title')){
            var element_title = $(foxislide_element).find('.foxislide_title');
            $(foxislide_element).animate({'height':(element_title.outerHeight()+image_height)},
              settings.speed);
            element_title.fadeIn(settings.speed);
          }
        });
        $(foxislide_element).css({'z-index':getZindex(foxislide_element)});
      }
      preload_img.src = $(element).attr('href');
    }

    function close(element){
      var origin = $(images_array[$(element).find('.foxislide_origin').text()]);
      var origin_image = origin.find('img');
      var element_width = origin_image.width();
      var element_height = origin_image.height();
      var element_top = origin_image.offset().top;
      var element_left = origin_image.offset().left;
      $(element).find('.foxislide_title').fadeOut(settings.speed);
      $(element).animate({'width':element_width, 'height':element_height,
        'top':element_top, 'left':element_left}, settings.speed);
      $(element).find('img').animate({'width':element_width, 'height':element_height,
        'top':element_top, 'left':element_left}, settings.speed, function(){
        $(images_array[$(element).find('.foxislide_origin').text()]).css('visibility', 'visible');
        $(element).hide().find('img').hide();
      });
    }

    function getZindex(element){
      var highest_zindex = $(element).css('z-index');
      $('body').find('div[id^="foxislide"]').each(function(){
        if($(this).css('display') != 'none'){
          var this_zindex = $(this).css('z-index');
          highest_zindex = (highest_zindex > this_zindex) ? highest_zindex : this_zindex;
        }
      });
      return ++highest_zindex;
    }

		function getScroll(){
      scroll_top = $(document).scrollTop();
      scroll_left = $(document).scrollLeft();
		}

    function getSize(){
      window_height = $(window).height();
      window_width = $(window).width();
    }
  }
})(jQuery);

