if(!SAPO.Widget || typeof(SAPO.Widget) == 'undefined') {
    SAPO.namespace('Widget');
}

SAPO.Widget.Rating = function(element, elmMessages, hash, options, defaultRating) {

    this.init(element, elmMessages, hash, options, defaultRating);
}; 

SAPO.Widget.Rating.prototype = {

    init: function(element, elmMessages, hash)
    {
        var options = Object.extend({
                    total: 5, 
                    image: false,
                    imageOver: false,
                    imageHalf: false,
                    url: false,
                    logged: false,
                    messages: [],
                    method: 'post',
                    variable: 'rate',
                    hashVariable: 'hash'
                }, arguments[3] || {});

        try {
            this.element = document.getElementById(element);

            if(typeof(elmMessages) != 'undefined' && elmMessages != false) {
                this.elmMessages = document.getElementById(elmMessages);
            }

            if(typeof(arguments[4]) == 'undefined') {
                this.defaultRating = 0;
            } else {
                this.defaultRating = Number(arguments[4]);
            }
            this.defaultImageSrc = [];

            this.hash = hash;
            
            this.options = options;
        
            // 
            // check for image and url
            //
            if(!this.options.image || !this.options.url) {
                alert('Options "image" and "url" are required.');
                return;
            }
            // 
            // check for Ajax.Request or YAHOO.util.Connection
            if((typeof(Ajax) == 'undefined') && (typeof(YAHOO.util.Connection) == 'undefined')) {
                alert('Ajax.Request or YAHOO.util.Connection are required');
                return;
            }
            if(typeof(Event) == 'undefined' && typeof(YAHOO.util.Event) == 'undefined') {
                alert('Prototype Event or YAHOO.util.Event are required');
                return;
            }

            if(this.options.messages.length == this.options.total) {
                this.hasMessages = true;
            } else {
                this.hasMessages = false;
            }

            if(!this.options.imageOver) {
                this.options.imageOver = this.options.image;
            }
            if(!this.options.imageHalf) {
                this.options.imageHalf = this.options.imageOver;
            }

            this.active = false;
            
            this.sto = false;

            this.writeImages();

        } catch(e) { }
    }, 

    writeImages: function() 
    {
        var aImgs = this.element.getElementsByTagName('IMG');
        for(var i=(aImgs.length - 1); i >= 0; i--) {
            aImgs[i].parentNode.removeChild(aImgs[i]);
        }

        var media = this.calculateMedia(this.defaultRating);
        for(var i=0; i < this.options.total; i++) {
            this.element.appendChild(this.genImageElement(i, media));
        }
    },

    genImageElement: function(ident, media)
    {
        var img = document.createElement('IMG');
        //img.src = this.options.image;
        if(media > ident && media < (ident + 1)) {
            img.src = this.options.imageHalf;
        } else if(media > ident) {
            img.src = this.options.imageOver;
        } else if(media <= ident) {
            img.src = this.options.image;
        }
        img.border = '0';
        img.alt = '';
        img.setAttribute('ident', ident);
        
        if(this.options.logged) {
          this.addOnMouseOver(img);
          this.addOnMouseOut(img);
          this.addOnClick(img);
        }

        return img;
    }, 

    genSimpleImageElement: function(ident, media) 
    {
        var img = document.createElement('IMG');
        if(media > ident && media < (ident + 1)) {
            img.src = this.options.imageHalf;
        } else if(media > ident) {
            img.src = this.options.imageOver;
        } else if(media <= ident) {
            img.src = this.options.image;
        }
        img.border = '0';
        img.alt = '';

        return img;
    },

    addOnMouseOver: function(elm) 
    {
        if(this.options.imageOver) {
            Event.observe(elm, 'mouseover', this.onMouseOver.bindAsEventListener(this));
        }
    },
    onMouseOver: function(e)
    {
        this.active = true;
        
        if(this.sto) {
          clearTimeout(this.sto);
          this.sto = false;
        }

        var elm = Event.findElement(e, 'IMG');
        var ident = elm.getAttribute('ident');

        this.showMessage(ident);

        var aImgs = this.element.getElementsByTagName('IMG');
        for(var i=0; i < aImgs.length; i++) {
            if(i > ident) {
                aImgs[i].src = this.options.image;
                //break;
            } else {
                aImgs[i].src = this.options.imageOver;
            }
        }
    },

    addOnMouseOut: function(elm) 
    {
        if(this.options.imageOver) {
            Event.observe(elm, 'mouseout', this.onMouseOut.bindAsEventListener(this));
        }
    },
    onMouseOut: function(e)
    {
        this.active = false;
        var elm = Event.findElement(e, 'IMG');
        var ident = elm.getAttribute('ident');
        
        this.showMessage();

        var aImgs = this.element.getElementsByTagName('IMG');
        for(var i=0; i < aImgs.length; i++) {
            aImgs[i].src = this.options.image;
            //if(i == ident) {
            //    break;
            //}
        }
        this.sto = setTimeout(function() {
                    if(!this.active) {
                        this.writeImages();
                    }
                }.bind(this), 1000);
    },

    addOnClick: function(elm)
    {
        Event.observe(elm, 'click', this.onClick.bindAsEventListener(this));
    },
    onClick: function(e)
    {
        var elm = Event.findElement(e, 'IMG');
        var ident = elm.getAttribute('ident');

        if(this.options.method == 'post') {
            new Ajax.Request(this.options.url, {method:'post', postBody:this.options.variable+'='+ident+'&'+this.options.hashVariable+'='+this.hash, onSuccess:this.onClickSuccess.bind(this)});
        } else if(this.options.method == 'get') {
            new Ajax.Request(this.options.url, {method:'get', parameters:this.options.variable+'='+ident+'&'+this.options.hashVariable+'='+this.hash, onSuccess:this.onClickSuccess.bind(this)});
        }
    },
    onClickSuccess: function(req)
    {
        if(req != null) {
            var res = eval('['+req.responseText+']')[0];
            var ratingPercent = res.rating;

            if(typeof(res.message) != 'undefined' && res.message != null) {
                this.elmMessages.innerHTML = res.message;
            } 
        } else {
            var ratingPercent = 0;
        }
        this.setDefault(ratingPercent);
    },

    showMessage: function(id)
    {
        if(this.hasMessages) {
            if(id && typeof(id) != 'undefined') {
                this.elmMessages.innerHTML = this.options.messages[id];
            } else {
                this.elmMessages.innerHTML = '';
            }
        }
    },

    setDefault: function(ratingPercent)
    {
        var aImgs = this.element.getElementsByTagName('IMG');
        for(var i=(aImgs.length - 1); i >= 0; i--) {
            aImgs[i].parentNode.removeChild(aImgs[i]);
        }
        // add default images 
        var media = this.calculateMedia(ratingPercent);

        for(var j=0; j < this.options.total; j++) {
            this.element.appendChild(this.genSimpleImageElement(j, media));
        }
    },

    calculateMedia: function(ratingPercent) 
    {
        ratingPercent = ratingPercent / 100;

        var media = this.options.total * ratingPercent; 
        var intMedia = Math.round(media);
        var decimal = media - intMedia; 
        var valor = 0;
        if((decimal >= 0 && decimal <= 0.25) || (decimal >= -0.25 && decimal <= 0)) {
            valor = intMedia;
        } else if ((decimal > 0.25 && decimal < 0.75) || (decimal > -0.75 && decimal < -0.25)) {
            if(decimal < 0) {
                valor = intMedia - 0.5;
            } else {
                valor = intMedia + 0.5;
            }
        }
        return valor;
    },

    debug: function(txt)
    {
        //document.getElementById('debug').innerHTML += txt+'<br />';
    }
};

