/** 
*   Плагин jquery.kiwi_viewer.js 
*   
*   @author Isaev Roman ( romis.bbx@gmail.com )
*   @firma BlackBox ( http://www.blackbox.ru/ )
*   @modufy_date 17.03.10
*   @version 1.3 beta
*   
*/

(function($) { 

  function getRandomInt(min, max)
  {
      return Math.floor(Math.random() * (max - min + 1)) + min;
  }

	// constructor ( jel - JqueryELement )
	function Kiwi_viewer(jel, ops) 
  {          
      var self = this;
      
      var kw_window = jel.find('ul:first')
        .addClass('kw_window');
      
      var count_items = 0;
      if (ops.itemArray.length == 0){
          count_items = kw_window.find('li').length;
      } else {
          count_items = ops.itemArray.length; 
          var st = '';
          for(i=0; i<count_items; i++){
            st += '<li></li>';
          }
          kw_window.html(st);
      } 
      
      var kw_items = kw_window.find('li')
        .hide();
      var curr_item_index = null; // индекс текущего элемента
      
      // clock      
      jel.append('<div class="clock"> </div>');
      jel.clock = {
          active: false,
          timer: 0,
          iteration: 11     
      }
                           
  		// methods
  		$.extend(this, {
  		
    			getOptions: function() {
            return ops;	
    			},
  			
    			getItems: function() {
            return kw_items;	
    			},
    			
    			getCountItems: function() {
            return count_items;	
    			},
    			
    			getCurrItemindex: function() {
            return curr_item_index;	
    			},
          
      		preloadItem: function(index, clock, onPreloadItem)
      		{ 
              clock = clock || false; 
              var item = kw_items.eq(index);
              
              if ( item.data('is_load') ) { 
                  if ( $.isFunction(onPreloadItem) ){
                      onPreloadItem(index);
                  } 
              } else {
                  var onPreload = function()
                  {
                      item.data('is_load', true);
                                        
                      var w = item.width();                  
                      var h = item.height();
                      item.data('it_width', w);
                      item.data('it_height', h); 
                                       
                      if (clock){
                        self.removeClock();
                      }    
                                
                      if ( $.isFunction(onPreloadItem) ){
                          onPreloadItem(index);
                      }               
                  }
                  
                  if (clock){
                    self.addClock();
                  }
                  item.html(ops.itemArray[index]);
                  
                  var item_imgs = item.find('img');          
                  if (item_imgs.length == 0) {
                      onPreload();
                  } else {                  
                      /* если картинки подгрузились из кеша, то событие load не сработает
                      поэтому проверяем заранее */
                      var comp = true;                      
                      for(i=0; i<item_imgs.length; i++){
                          comp = comp && item_imgs[i].complete;
                      } 
                      
                      if(comp){
                          onPreload();              
                      } else {                     
                          item_imgs.load(function()
                          {
                              $(this).data('complete', true);
                              var is_load = item.data('is_load');
                              if ((is_load === undefined) || !is_load )
                              {                                  
                                  var item_imgs = item.find('img');                                     
                                  var comp = true;
                                  item_imgs.each(function() {	                                     
                                      comp = comp && $(this).data('complete') ;
                                  });
                                    
                                  if(comp){
                                      onPreload();                                           
                                  }  
                              }                                                            
                          });             
                      }          
        
                  } 
              }               
      		},
      		
          loadItem: function(index, onLoadEvent)
          {
              if ( (index != curr_item_index) && (index < count_items) )
              {
                  var item = kw_items.eq(index); 
                  if (ops.itemArray.length == 0){
                      jel.showItem(index, onLoadEvent);              
                  } else {
                      self.preloadItem(index, true, function(index){
                          jel.showItem(index, onLoadEvent);
                      });            
                  }
              } /*else {
                alert('Error: Недопустимый индекс (index = ' + index + ')' + '\n' 
                      + 'curr_item_index = ' + curr_item_index + '\n' 
                      + 'count_items ' + count_items );
              }*/                  	             
          },
          
          addEventonShowItem: function(event)
          {
              ops.onShowItem = event;
          },
          
          loadNext: function(circle, onLoadEvent)
          {
              circle = circle || false;
              if(curr_item_index < count_items - 1)
              {
                  self.loadItem(curr_item_index + 1, onLoadEvent);       
              } else if (ops.circle || circle){
                  self.loadItem(0, onLoadEvent);
              }           
          },
          
          loadPrev: function(circle, onLoadEvent)
          {
              circle = circle || false;
              if(curr_item_index > 0)
              {
                  self.loadItem(curr_item_index - 1, onLoadEvent);         
              } else if (ops.circle || circle){
                  self.loadItem(count_items - 1, onLoadEvent);
              }          
          },
          
          loadRandom: function(onLoadEvent)
          {
              var new_item = getRandomInt(0, count_items-1);
              // исключаем текущий элемент
              if ( (new_item == curr_item_index) && (curr_item_index !== null) )
              {
                  if (curr_item_index < (count_items - curr_item_index - 1) )
                  {  
                      new_item = getRandomInt(curr_item_index+1, count_items-1);
                  } else {
                      new_item = getRandomInt(0, curr_item_index-1);
                  }
              }
              self.loadItem(new_item, onLoadEvent);         
          },
          
      		addClock: function()
      		{ 
      		    jel.clock.active = true;
      		    setTimeout(function(){
                  if (jel.clock.active)
                  {        
                      jel.find('div.clock').show();                    
              		    clearInterval(jel.clock.timer);
              		    jel.clock.timer = setInterval(function()
                      {
                          var val = jel.clock.iteration*40;
                          jel.find('div.clock').css('background-position','0 '+ val + 'px');   
                          if (jel.clock.iteration > 0){
                              jel.clock.iteration--;
                          } else {
                              jel.clock.iteration = 11;
                          }                
                      }, 100);
                  }                        
              }, ops.clock_delay);
      		},
      		
      		removeClock: function()
      		{ 
      		    jel.clock.active = false;
              clearInterval(jel.clock.timer);
              jel.find('div.clock').hide();
      		}           
  			
  		});
  		
      // выбор первого видимого элемента  		
  		jel.select_start_item = function()
  		{          
          switch (ops.start_item) {
             case 'first':
                self.loadItem(0);
                break
             case 'last':
                self.loadItem(count_items-1);
                break
             case 'center':
                self.loadItem( Math.floor( (count_items - 1)/2) );
                break
             case 'random':
                self.loadRandom();
                break
             default:
                self.loadItem(0);
                break
          }
      }
              		  		
  		jel.showItem = function(index, onShowEvent)
  		{  
          var show_item = kw_items.eq(index);
          if (curr_item_index === null){
              show_item.show();
          } else {          
              var cur_item = kw_items.eq(curr_item_index);
              
              var get_direction = function()
              {
                  return (curr_item_index < index) ? 
                         !( (index == count_items - 1) && (curr_item_index == 0) ) : 
                         ( (index == 0) && (curr_item_index == count_items - 1) );              
              } 
                           
              switch (ops.effect) 
              {
                 case 'fade':
                    show_item.css({ opacity: 0 }).show();
                    cur_item.animate({ opacity: 0 }, ops.animate_time, function(){
                        $(this).hide().css({ opacity: 1 });
                    });
                    show_item.animate({ opacity: 1 }, ops.animate_time);
                    break
                    
                 case 'slide-hor':
                    var show_width = show_item.width();
                    var cur_width = cur_item.width();
                    if ( get_direction() ){
                        // next
                        show_item
                          .css({ zIndex: 0 })
                          .show();
                        cur_item
                          .css({ zIndex: 1 })
                          .animate({ width: 0 }, ops.animate_time, function(){
                              $(this).hide().css({ width: cur_width + 'px' });
                          });                       
                    } else {
                        // prev
                        cur_item.css({ zIndex: 0 });
                        show_item
                          .css({ zIndex: 1, width: 0 })
                          .show()
                          .animate({ width: show_width + 'px' }, ops.animate_time, function(){
                              cur_item.hide();    
                          }); 
                    }                     
                    break
                    
                 case 'slide-vert':
                    var show_height = show_item.height();
                    var cur_height = cur_item.height();
                    if ( get_direction() ){
                        // next
                        show_item
                          .css({ zIndex: 0 })
                          .show();
                        cur_item
                          .css({ zIndex: 1 })
                          .animate({ height: 0 }, ops.animate_time, function(){
                              $(this).hide().css({ height: cur_height + 'px' });
                          });                       
                    } else {
                        // prev
                        cur_item.css({ zIndex: 0 });
                        show_item
                          .css({ zIndex: 1, height: 0 })
                          .show()
                          .animate({ height: show_height + 'px' }, ops.animate_time, function(){
                              cur_item.hide();    
                          }); 
                    }                     
                    break

                 case 'scroll-hor':
                    var show_width = show_item.width();
                    var cur_width = cur_item.width();
                    var show_val = '';
                    var cur_val = '';                                       
                    if ( get_direction() ){
                        // next
                        show_val = show_width + 'px';
                        cur_val = '-' + show_width + 'px';                        
                    } else {
                        // prev
                        show_val = '-' + show_width + 'px';
                        cur_val = show_width + 'px'; 
                    }                    
                    show_item.css({ left: show_val }).show();                    
                    cur_item.animate({ left: cur_val }, ops.animate_time, function(){
                        $(this).hide().css({ left: '0' });
                    });
                    show_item.animate({ left: '0px' }, ops.animate_time);                             
                    break
                                        
                 case 'scroll-vert':
                    var show_height = show_item.height();
                    var cur_height = cur_item.height();
                    var show_val = '';
                    var cur_val = '';
                    if ( get_direction() ){
                        // next
                        show_val = show_height + 'px';
                        cur_val = '-' + show_height + 'px';                        
                    } else {
                        // prev
                        show_val = '-' + show_height + 'px';
                        cur_val = show_height + 'px'; 
                    }                    
                    show_item.css({ top: show_val }).show();                    
                    cur_item.animate({ top: cur_val }, ops.animate_time, function(){
                        $(this).hide().css({ top: '0' });
                    });
                    show_item.animate({ top: '0px' }, ops.animate_time);                             
                    break
                    
                 default: // 'none'
                    cur_item.hide();
                    show_item.show();
                    break
                  
              }
              cur_item.removeClass('current');
          }
          
          show_item.addClass('current');               
          curr_item_index = index;
          
          if ( $.isFunction(ops.onShowItem) ){
              ops.onShowItem(index);
          }

          if ( $.isFunction(onShowEvent) ){
              onShowEvent(index);
          }                   
           
          jel.state_buttons();  
          
          if (ops.height == 'auto')
          {              
              self.preloadItem(index, false, function(index){
                var h = kw_window.find('li').eq(index).data('it_height');
                //alert(h + ' / ' + index); 
                kw_window.animate({height: h},ops.animate_time);
              });                                     
          }    
          
          /*var w = show_item.width();
          var h = show_item.height();
          //alert(jel.html() + " w: " + w + " h: " + h);
          
          var item_l = Math.floor((kw_window.width() - w)/2);
          var item_t = Math.floor((kw_window.height() - h)/2);
          
          show_item.css({
            left: item_l + 'px',
            top: item_t + 'px'
          });*/
      }
                  
      // обработчики событий кнопок
      
      // next
      jel.find(ops.btn_next).click(function()
      {
          self.loadNext();
          return false;     
      });
      
      // prev
      jel.find(ops.btn_prev).click(function()
      {
          self.loadPrev();
          return false;     
      });
      
      // end обработчики событий кнопок
      
      // Определяет скрывать кнопки "НАЗАД" и "ВПЕРЕД" или нет
      jel.state_buttons = function()
      {
          if (!ops.circle)
          {
              // next
              if(curr_item_index >= count_items - 1)
              {
                  jel.find(ops.btn_next).addClass('disabled');
              } else {
                  var btn = jel.find(ops.btn_next);
                  if ( btn.hasClass("disabled") ){              
                    btn.removeClass('disabled');
                  }
              }  
              
              // prev
              if(curr_item_index <= 0)
              {
                  jel.find(ops.btn_prev).addClass('disabled');
              } else {
                  var btn = jel.find(ops.btn_prev);
                  if ( btn.hasClass("disabled") ){              
                    btn.removeClass('disabled');
                  }
              }
          } 
      }
      
      if (count_items > 0){
          jel.select_start_item();
      }
          		
	}

  // jQuery plugin implementation
  $.fn.kiwi_viewer = function(ops)
  {  
  		var el = this.eq(0).data('kiwi_viewer');
  		if (el) { return el; }
      
      // default settings
      var ops = $.extend({
          btn_next: 'a.btn_next', //селектор для выбора кнопки движения вперед
          btn_prev: 'a.btn_prev', //селектор для выбора кнопки движения назад
          start_item: 'first', // first / center / last / random
          //content_type: 'content', // content / array
          //window_size: 'auto', // auto / css
          effect: 'none', // none / fade / slide-vert / slide-hor / scroll-vert / scroll-hor
          animate_time: 500, // время анимации
          //one_animate: false, // одна анимация за раз
          circle: false, // цикличиское движение по кругу
          itemArray: [],
          height: 'css', // auto / css
          clock_delay: 500, // задержка перед появлением часов при прелоуде
          onShowItem:	null /* событие происходит после подгрузки элемента 
                              show_item - ссылка на подгруженный элемент */ 
      },ops);
          
  		this.each(function() {			
  			el = new Kiwi_viewer($(this), ops);
  			$(this).data('kiwi_viewer', el);	
  		});
  		
  		return this;    
  };

})(jQuery);



