/**
 * class selfRating
 * 
 * @author Grzegorz Balcewicz
 * 
 * Klasa zarzadzajaca zdarzeniami dla rating baru. Rating bar musi byc stworzony
 * w nastepujacy sposob:
 *  - deklarujemy zmienna przed divem,
 *  - reprezentacja ratingu to dwa divy, jeden zagniezdzony w drugim,
 *  - [opcjonalne] dodajemy zdarzenia onmouseover, onmouseout, jezeli ma byc 
 *    mozliwosc interakcji z eventami mmyszki,
 *  - za divami do wczzesniej zadeklarowanej zmiennej tworzymy instancje klasy,
 *  - [opcjonalne] definiujemy dodatkowe akcje dla eventow (patrz przyklad)
 * 
 * Wymagania:
 * -------------
 * 
 *  - pola w stylu diva zewnetrznego:
 *    - width (szerokosc, po utworzeniu skrypt zmienia jej wartosc na maxValue * szerokosc_obrazku),
 *    - height (wysokosc);
 *	  - position (wymagane przede wszystkim przez ie);
 *	  - background (z url i repeat-x);
 *  - pola w stylu diva wewnetrznego:
 *    - height
 *    - background (z url i repeat-x);
 *
 * Przyklad uzycia:
 * ------------------
 *
 *   <style type="text/css">
 *     #rating {
 *			margin: 0;
 *			padding: 0;
 *			width: 160px;
 *			height: 32px;
 *			position: relative;
 *			background: url('/images/star_off.png') repeat-x;
 *			cursor: pointer;
 *		}
 *		
 *		#rating div#rated
 *		{
 *			height: 32px;
 *			background: url('/images/star_on.png') repeat-x;
 *		}
 *   </style>
 *
 *   <script type="text/jaavascript">
 *   	var ratingBar = null;  // deklaracja zmiennej dla selfRatingu
 *   </script>
 *   
 *   <!-- Rating bar begin -->
 *   <div id="rating" class="stars" onmouseover="ratingBar.startRate(event);" onmouseout="ratingBar.stopRate();">
 *     <div id="rated"><!--  --></div>
 *   </div>
 *   <!-- Rating bar end -->
 *   
 *   <script type="text/javascript">
 *     ratingBarratingBar = new selfRating('rating', 'rated', 5, 32, 1);
 *     
 *      //* opcjonalnie 
 *      selfRating_sr.onclick = function(t)
 *		{
 *		  alert('Zmieniono z ' + t.value + ' na ' + t.newValue);
 *        t.value = t.newValue;
 *		}
 *   </script>
 * 
 * @param starsId   - id diva dla tla ('wylaczonych obrazkow') ratingu
 * @param starsOnId - id diva dla aktywnych obrazkow ('wlaczonych') ratingu
 * @param maxValue  - maksymalna ocena
 * @param starWidth - szerokosc pojedynczego obrazku symbolizujacego jednostke oceny
 * @param step      - krok oceny (np. 0.5 umozliwia dodawanie polowek oceny, natomiast 10 skok oceny bedzie co 10
 * @return
 */
function selfRating(starsId, starsOnId, maxValue, starWidth, step)
	{
		/**
		 * numeric: aktualna ocena 
		 */
		this.value = 0;
		this.maxValue = maxValue - 1;
		this.step = step != null ? step : 0;

		/**
		 * numeric: wartosc po kliknieciu w 'pasek' ratingu
		 */
		this.newValue = null;
		
		/**
		 * funkcje uruchamiane dla odpowiadajacym im eventom
		 * function(t), gdzie pod zmienna t dostepny jest obiekt selfRating  
		 */
		this.onclick = null;
		this.onmouseon = null;
		this.onmouseout = null;
		
		var that = this;
		var starDiv = document.getElementById(starsId);
		var starOnDiv = document.getElementById(starsOnId);
	
		/**
		 * Ustawia odpowiednia szerokosc diva z aktywnymi gwiazdkami
		 * 
		 * @param e - event
		 * @return
		 */
		function setStars(e)
		{
			var x = 0;
	
			if (Math.max(navigator.userAgent.toLowerCase().indexOf('msie'),0))
			{
				x = window.event.clientX + document.documentElement.scrollLeft;
			}
			else
			{
				x = e.pageX;
			}
			
		
			if (starOnDiv != null)  
			{
				that.newValue = 0;
				
				if (that.step == 0)
				{
					that.newValue = (x - starDiv.offsetLeft); 
					starOnDiv.style.width = Math.min(that.newValue, (that.maxValue + 1) * starWidth) + 'px';
					that.newValue = Math.floor(that.newValue * (that.maxValue / starDiv.clientWidth)) + 1;
				}
				else
				{
					var segmentWidth = (starWidth * that.step);
					that.newValue = (Math.floor((x - starDiv.offsetLeft) / segmentWidth) + 1) * segmentWidth;

					starOnDiv.style.width = Math.min(that.newValue, (that.maxValue + 1) * starWidth) + 'px';
					that.newValue = (Math.floor((x - starDiv.offsetLeft) / segmentWidth) + 1) / (starDiv.clientWidth / segmentWidth) * (that.maxValue + 1);
				}

			}
		}
			
		/**
		 * Funkcja, ktora powinna zostac odpalona dla zdarzenia onmouseover dla diva
		 * z tlem obrazkow ratingu
		 * 
		 * @param e - event
		 */
		this.startRate = function(e)
		{
			setStars(e);
			
			if (that.onmouseon !== null)
			{
				that.onmouseon(that);
			}
			
			document.onmousemove = function(e){
				setStars(e);
				
				if (that.onmouseon !== null)
				{
					that.onmouseon(that);
				}
			};
			document.onmousedown = function(e){
				if (that.onclick !== null)
				{
					that.onclick(that);
				}
			}
		}
		
		/**
		 * Funkcja, ktora powinna zostac dodana dla eventu onmouseout w divie z tlem
		 * nieaktywnych obrazkow ratingu.
		 * 
		 * @return
		 */
		this.stopRate = function stopRate()
		{
			document.onmousemove = null;
			document.onmousedown = null;
			if (starOnDiv != null) 
			{
				starOnDiv.style.width = (this.value / (this.maxValue+1)) * starDiv.clientWidth + 'px';
			}
			
			if (that.onmouseout !== null)
			{
				that.onmouseout(that);
			}
		}
		
		/**
		 * Ustawia odpowiedia wartosc dla rating baru.
		 *
		 * @param numeric val
		 */
		this.setValue = function(val)
		{
			
			if (val > 0)
			{
				that.value = val;
			}
			
			that.stopRate();
		}
	};
