/**
 * Modul umozliwiajacy tworzenie i zapisywanie list rankingowych dla plebiscytow
 * @param {Object} local_conf
 */
(function() {
	
	PlebisciteRanking = {};
	/**
	 * Referencja 
	 */
	var _self = PlebisciteRanking;
	
	/**
	 * Lokalne zmienne
	 */
	var _event = {}, _controller = {}, _view = {} , _config = {};
	
	/**
	 * @var obiekt z konfiguracja domyslna
	 */
    _config = {
		listId 				: '',		// id listy rankingowej - element ul
		listUpClassName		: 'up',		// klasa css okreslajaca strzalke do gory
		listDownClassName	: 'down',   // klasa css okreslajaca strzalke w dol
		listNoUpClassName	: 'noUp',   // klasa css okreslajaca wygaszona strzalke do gory
		listNoDownClassName	: 'noDown', // klasa css okreslajaca wygaszona strzalke w dol
		listPositionPrefix  : 'i'		// prefix przed id elementu pojawiajacy sie w elementach listy ( li )
	};
	
	
	
	/**
	 * Podmienia dane listy, na podstawie id elemnetu 
	 * zmiena jego pozycje i okresla o ile sie przesunal 
	 * wzgledem swojej bazowej pozycji
	 * @param {Integer} id 		- id elementu
 	 * @param {Integer} position- pozycja elementu
	 * @param {Integer} shift   - przesuniecie
	 */
	_config.changeListData = function( id , position , shift ){
		_localData[ id ].position = position
		_localData[ id ].shift += shift;
	}
	
	_config.working = false;
	
	/**
	 * Czy akcja zostala zaincjalizowana przez ui sortable
	 */
	_config.sortableAction = false;
	
	/**
	 * Dlugosc listy otrzymanej z serwera
	 */
	var _totalListCount = 0;
	
	var _localData = null;
	/**
	 * Lokalna lista rankingowa
	 */
	var _rankingList = null;
	
	/**
	 * Inicjalizacja eventow - podpinanie + obsluga zdarzen
	 */
	var _eventInit = function(){
		/**
		 * Podczepia wszystkie wymagane eventy - klikniecie w liste rankingowa
		 * @access private
		 */
		_event.attach = function(){
			jQuery('#' + _config.listId ).bind( 'click', function( event ){			
				event.preventDefault();	
				var target = event.target;				
				if( target.nodeName.toLowerCase() == 'input' && target.type.toLowerCase() == 'submit' ){
					_event.handleListClick( target );
				}
			})
			
		}
		
		/**
		 * Obsluga klikniecia w liste rankingowa - sprawdzenie celu i przekazanie informacji do kontrolera
		 * celem przesuniecia elementu w gore lub w dol
		 * Granice ( element pierwszy i ostatni ) sa wykluczane na podstawie klas css
		 * jezeli element ma klase 'noUp' lub 'noDown' nie jest obslugiwany @see _config
		 * @param {Object} target - DOM element klikniety
		 */
		_event.handleListClick = function( target ){
			var elementValue = parseFloat( target.value );
			var element = jQuery( target ).parent().parent().parent()[0];
			if ( element.nodeName.toLowerCase() == 'li' &&  !_config.working && !_config.sortableAction ) {		
				_config.working = true;			
				var elementPosition = parseFloat( element.className.substr( _config.listPositionPrefix.length ) );
				/**						
				 * Obslugujemy tylko klasy klikalne
				 */
				if ( target.className == _config.listUpClassName ) { // element ma sieprzesunac do gory
					_controller.moveElementUp( element, elementPosition, elementValue )
				}
				if ( target.className == _config.listDownClassName ) { // element na sie przesunac na dol
					_controller.moveElementDown( element , elementPosition, elementValue )
				}
			}					
		}
		
	}
	
	/**
	 * Inicjalizacja eventow - glowna kontrola nad przebiegiem akcji po odebraniu zdarzenia
	 */
	var _controllerInit = function(){
		
		/**
		 * Przesuwa wybrany element do gory,
		 * @param {Object}  element		- wybrany element
		 * @param {Integer} position	- pozycja elementu w momencie klikniecia
	 	 * @param {Integer} value		- id elementu
		 */
		_controller.moveElementUp = function( element, position , value ){
			/**
			 * Okreslamy element ktory jest powyzej, bedzie on zamieniony miejscami z naszym elementem
			 */
			var upper = jQuery(element).prev();
			/**
			 * Okreslamy id elementu ktory jest powyzej
			 */
			var upperValue = parseFloat( jQuery( upper ).find('input')[0].value );
			
			_view.checkBorderCondition( element, upper, position , 'up' )
			
			_controller.moveElementTo( value,  position-1, 1 )
			_controller.moveElementTo( upperValue,  position+1, -1 )
			
			_view.changeElementPosition( element, value, position - 1 );
			_view.changeElementPosition( upper, upperValue, position );
			if( !_config.sortableAction ){		
				jQuery( element ).after( jQuery( upper ) );
			}
		}
		
		/**
		 * Przesuwa jeden element na okreslona pozycje
		 */
		_controller.moveElementTo = function( id , position, shift ){
			_config.changeListData( id , position, shift )
		}
		
		/**
		 * Przesuwa element na dol
		 * @param {Object}  element		- element
		 * @param {Integer} position	- pozycja elementu
	 	 * @param {Integer} value		- id elementu
		 */
		_controller.moveElementDown = function( element, position , value ){
			/**
			 * Okreslamy element ktory jest ponizej, bedzie on zamieniony miejscami z naszym elementem
			 */
			var down = jQuery( element ).next();
			/**
			 * Okreslamy id elementu ktory jest ponizej
			 */
			var downValue = parseFloat( jQuery( down ).find('input')[0].value );
			
			
			_view.checkBorderCondition( element , down, position, 'down' )
			
			
			_controller.moveElementTo( value,  position+1, -1 )
			_controller.moveElementTo( downValue,  position-1, 1 )
			
			_view.changeElementPosition( element, value, position + 1 );
			_view.changeElementPosition( down, downValue, position );
			if( !_config.sortableAction ){		
				jQuery( element ).before( jQuery( down ) );
			}
		}
		
		
		_self.moveElementUp = _controller.moveElementUp
	}
	
	
	
	/**
	 * Inicjalizaja funkcji odpowiedzialny za zmiany view
	 */
	_viewInit = function(){
		
		_view.changeElementPosition = function( el, id, pos ){
			jQuery( el ).find('.result em').html( pos )
			jQuery( el )[0].className = _config.listPositionPrefix + ( pos )
			
			if (_localData[id].shift == 0)	jQuery(el).find('span')[0].className = 'arrow';
			if (_localData[id].shift > 0 )	jQuery(el).find('span')[0].className = 'arrow up';
			if (_localData[id].shift < 0 )	jQuery(el).find('span')[0].className = 'arrow down';
			
			if (_localData[id].shift == 0) jQuery( el ).find('.arrow em' ).html('');
			else jQuery( el ).find('.arrow em' ).html( _localData[id].shift );
			_config.working = false;
			
		}
		
		_view.checkBorderCondition = function( el1, el2, position, dir ){
			/**
			 * Podmiana nazw klas na granicy - jezeli jestesmy na przedostatnim miejscu i przesuwamy w dol
			 */
			
			if( position == ( _totalListCount-1 ) && dir == 'down' ){
				jQuery( el1 ).find('.navigation .'+_config.listDownClassName )[0].className = _config.listNoDownClassName;
				jQuery( el2 ).find('.navigation .'+_config.listNoDownClassName )[0].className = _config.listDownClassName;
			}
			/**
			 * Podmiana nazw klas na granicy - jezeli jestesmy na 1 miejscu i przesuwamy w dol
			 */
			if( position == 1 && dir == 'down' ){
				jQuery( el1 ).find('.navigation .'+_config.listNoUpClassName )[0].className = _config.listUpClassName;
				jQuery( el2 ).find('.navigation .'+_config.listUpClassName )[0].className = _config.listNoUpClassName;
			}
			/**
			 * Podmiana nazw klas na granicy - jezeli jestesmy na 2 miejscu i przesuwamy w gore
			 */
			if( position == 2 && dir == 'up' ){
				jQuery( el1 ).find('.navigation .'+_config.listUpClassName )[0].className = _config.listNoUpClassName;
				jQuery( el2 ).find('.navigation .'+_config.listNoUpClassName )[0].className = _config.listUpClassName;
			}
			/**
			 * Podmiana nazw klas na granicy - jezeli jestesmy na ostatnim miejscu i przesuwamy w gore
			 */
			if( position == _totalListCount && dir == 'up' ){
				jQuery( el1 ).find('.navigation .'+_config.listNoDownClassName )[0].className = _config.listDownClassName;
				jQuery( el2 ).find('.navigation .'+_config.listDownClassName )[0].className = _config.listNoDownClassName;
			}
		}
	}
	
	
	_config.startPosition = 0;
	_config.endPosition = 0;
	
	/**
	 * Inicjalizacja modulu
	 * @param {Object} conf - konfugiracja zewnetrzna
	 * @param {Object} data - paczka danych incializujacych
	 */
	_self.init = function ( conf , data ) {
		
		_eventInit();
		_controllerInit();
		_viewInit();
		
		// ustawiamy wartosci poczatkowe + konfiguracja
		_totalListCount = data.totalCount;
		_localData = data.list;
		_config = jQuery.extend( _config , conf );
		
		
		//podpinamy eventy
		_event.attach();
		// wylaczamy stany disabled na inputach
		jQuery('#'+_config.listId+' li:first input.'+_config.listNoUpClassName )[0].removeAttribute('disabled');//.' + _config.listPositionPrefix + '1
		jQuery('#'+_config.listId+' li:last input.'+_config.listNoDownClassName )[0].removeAttribute('disabled'); //.' + _config.listPositionPrefix + _totalListCount + ' 
		
		jQuery('#'+_config.listId).sortable({
			 axis: 'y',
			 start	: function( event, ui ){
			 	_config.sortableAction = true;
				_config.working = true;
				_config.startPosition = jQuery('#'+_config.listId+' li').index( jQuery( ui.item ) );
		   		
			 },
			 change	: function( event, ui ){
			 	_config.working = false;
				_config.sortableAction = false;
			 },
			 stop	: function( event, ui ){
			 	_config.endPosition = jQuery('#'+_config.listId+' li').index( jQuery( ui.item ) );		   		
				_controller.sortableHandle( ui.item[0] );
				_config.working = false;
				_config.sortableAction = false;
			 },
			 update : function( event, ui ){
			 	_config.working = false;
				_config.sortableAction = false;
			 }
		});
		
		
		

		
		jQuery('#'+_config.listId+' li').mouseout( function(){
			jQuery(this).removeClass('hover');
		}).mouseover( function(){
			jQuery(this).addClass('hover');
		})
		
		jQuery('#'+_config.listId+' li img').each(function(){
			var src = jQuery(this).attr('src').replace('-C7.','-C303.');
			var alt = jQuery(this).attr('alt');
			jQuery(this).setFloatbox({
				boxConfig: {width: '800px', marginLeft: '-400px'},
				contentHtml: '<div class="image"><img src="' + src + '" alt="' + alt + '" /></div>',
				closeButtonHtml: '<div class="close-floatbox-button close-floatbox"><span>zamknij</span></div>',
				wrapperClass: 'articleEmbedPhoto'
			});
		})
		
		
	}
	
	_controller.sortableHandle = function( element ){
		
		// wszystkie elementy w dol
		if( _config.startPosition > _config.endPosition ){
			for( var i = _config.startPosition; i > _config.endPosition ; i--){
				var root = document.getElementById( _config.listId ).getElementsByTagName('li');
				var value = jQuery( root[i] ).find('input').val();
				_controller.moveElementTo( value,  i+1, -1 )
				_view.changeElementPosition( root[i], value, i + 1 );
			}
			var root = document.getElementById( _config.listId ).getElementsByTagName('li');
			var value = jQuery( root[_config.endPosition] ).find('input').val();
			
			_controller.moveElementTo( value,  _config.endPosition+1, _config.startPosition - _config.endPosition )
			_view.changeElementPosition( root[_config.endPosition], value, _config.endPosition + 1 );

			if( _config.endPosition == 0 ){
				_view.checkBorderCondition( root[0], root[1], 2 , 'up' )
			}
			if ( _config.startPosition == ( _totalListCount - 1)  ) {
				_view.checkBorderCondition( root[_config.endPosition], root[_totalListCount-1], _totalListCount , 'up' )
			}
			
			_config.sortableAction = false;
		}
		
		// wszystkie elementy do gory
		if ( _config.startPosition < _config.endPosition ) {
			for( var i = _config.startPosition; i < _config.endPosition ; i++){
				var root = document.getElementById( _config.listId ).getElementsByTagName('li');
				var value = jQuery( root[i] ).find('input').val();
				_controller.moveElementTo( value,  i+1 , 1 )
				_view.changeElementPosition( root[i], value, i+1 );
			}
			
			var root = document.getElementById( _config.listId ).getElementsByTagName('li');
			var value = jQuery( root[_config.endPosition ] ).find('input').val();
			
			_controller.moveElementTo( value,  _config.endPosition+1, _config.startPosition - _config.endPosition )
			_view.changeElementPosition( root[_config.endPosition], value, _config.endPosition + 1 );
			
			if( _config.startPosition == 0 ){
				_view.checkBorderCondition( root[_config.endPosition], root[0], 1 , 'down' )
			}
			if ( _config.startPosition == ( _totalListCount - 2 ) ) {
				_view.checkBorderCondition( root[ _totalListCount -1 ], root[_totalListCount - 2 ], _totalListCount - 1, 'down')
			} // przesuwam na sam koniec
			if ( _config.endPosition == ( _totalListCount - 1 ) && _config.startPosition != ( _totalListCount - 2 ) ) {
				_view.checkBorderCondition( root[ _totalListCount - 1 ], root[ _totalListCount - 2 ], _totalListCount - 1, 'down')
			}
			_config.sortableAction = false;
			
		}	
		
	}
	
	
})();

