// TODO figure out a way to reset the field
var defaultOptions = {
    baseImageName: 'star',
    imageType: 'png',
    halfStars: false,
    imagePath: '/images'
};

var Star = Class.create();
Object.extend(Star.prototype, {
    /**
     * Star constructor
     * @param parent StarRating parent of this star
     * @param index_ index in StarRating. AKA value
     * @param baseImagePath optional image base path name, defauts to parent.baseImageName useful for half stars
     */
    initialize: function(parent, index_, baseImagePath) {
        this.index = index_;
        this.parentId = parent.starField.id;
        //console.log('baseImagePath='+baseImagePath);
        this.imageName = (typeof baseImageName == 'undefined' ? parent.baseImageName : baseImagePath);
        
        this.parent = parent;
        this.spanId = this.parentId+'_star_'+index_;
        this.imageId = this.parentId+'_img_'+index_;
        
        this.body = Builder.node('span', {'class': 'star', 'id': this.spanId}, 
                                            [Builder.node('img', {'src': this.imageName+'_off.'+this.parent.imageType, 'class': 'off', 'id': this.imageId},'')]);
       
        this.saved = false;
    },
    /**
     * 'Renders' this star by appending to 'parentId' and attaches event handlers.
     */
    render: function() {
        //console.log("ParentId="+this.parentId);
        //console.log("Body="+this.body);
        $(this.parentId).appendChild(this.body);
        Event.observe(this.imageId, 'mouseover', this._mouseover.bindAsEventListener(this));
        Event.observe(this.imageId, 'mouseout', this._mouseout.bindAsEventListener(this));
        Event.observe(this.imageId, 'click', this._click.bindAsEventListener(this));
    },
    /**
     * Function for when this star is moused over
     */
    _mouseover: function(event) {
        this.parent._mouseover(this.index);
    },
    /**
     * Function for when this star is moused out
     */
    _mouseout: function(event) {
        this.parent._mouseout(this.index);
    },
    /**
     * Turns this star 'off' by changing the image to image base name+'off.png'
     */
    off: function() {
       
        $(this.imageId).setAttribute('src', this.imageName+'_off.'+this.parent.imageType);

    },
    /**
     * Turns this star 'on' by changing the image to image base name+'on.png'
     */
    on: function() {
        $(this.imageId).setAttribute('src', this.imageName+'_on.'+this.parent.imageType);
    },
    /**
     * Function for when this star is clicked
     */
    _click: function() {
        this.saved = true;
        this.parent._click(this.index);
    }

});
/**
 * StarRating will create a javascript enabled star rating system.
 * The resulting dom element will look like:
 *    <div id="containingDiv"> <!-- this div exists already on the page, not created by StarRating -->
 *          <div id="containingDiv_StarRating">
 *              <span id="containingDiv_StarRating_star_1" class="star">
 *                  <img id="containingDiv_StarRating_img_1" src="baseImageName_off.png" />
 *              </span>
 *              [Repeat maxRating times]
 *          </div>
 *          <input id="StarRating_name" type="hidden" name="name"/>
 *    </div>
 */
var StarRating = Class.create();
Object.extend(StarRating.prototype, {
    /**
     * Creates a new StarRating 'widget'
     * @param containingDivId id of the div to render inside of. Should already exist on page.
     * @param name name of the parameter that will be submitted with the value of this StarRating.
     * @param maxRating Maximum value. Rating value will be from 1 to maxRating.
     */    
    initialize: function(containingDivId, name, maxRating, options) {
        this._initializeOptions(options);
        this.currentRating = 0;
        this.stars = [];
        this.maxRating = maxRating;
        this.container = containingDivId;
        this.starField = document.createElement('div');
        this.starField.setAttribute('id', containingDivId+'_StarRating');
        this.name=name;
        this.currentIndex = 0;
        $(containingDivId).appendChild(this.starField);
        //console.log('about to create '+maxRating+' stars');
        
        this.stars = $R(1,this.maxRating).collect(this.createStar.bind(this));
        this.submitionField = Builder.node('input', {type:'hidden', name: this.name, id: 'StarRating_'+this.name});
    },
    /**
     * Renders this StarRating 'widget' inside containingDivId's element
     */
    render: function(index) {
        if (typeof index != 'undefined') this.currentIndex = index;
        
       /* var resetSpan = Builder.node('span', {id: 'reset_'+this.starField.id}, '');
        Event.observe(resetSpan, 'mouseover', this._mouseover.bind(this, 0));
        Event.observe(resetSpan, 'mouseout', this._mouseout.bind(this, 0));
        Event.observe(resetSpan, 'click', this._click.bind(this, 0));
        this.starField.appendChild(resetSpan); */
        this.stars.invoke('render');
        if (this.currentIndex > 0) {
            this._setStars(this.currentIndex);
        }
        $(this.container).appendChild(this.submitionField);
    },
    /**
     * Function to create a Star within this StarRating. Override for custom creation actions like different star image names.
     * @param index Index of which star is currently being created. Value from 1 to maxRating.
     */
    createStar: function(index) {
        //console.log('creating star');
        var image;
        if (this.halfStar) {
            var image = '';
            if (i % 2 == 0) {
                // right side
                image = this.baseImageName+'_right';
            } else {
                //left side
                image = this.baseImageName+'_left';
            }
        }
        return new Star(this, index, image);
    },
    
    _mouseover: function(index) {
        //console.log('Mouse over '+index);
       
        this._setStars(index);
    },
    _mouseout: function(index) {
        //console.log('Mouse out of '+index); 
        this._setStars(this.currentIndex);
    },
    _setStars: function(index, setSave) {
        var starIndex = index;
        var i =0;
        //console.log("turning on 1-"+index);
        for(; i < starIndex; i++) {
            this.stars[i].on();
            if (setSave) this.stars[i].save = true;
        }
        //console.log("turning off "+index+"-"+this.stars.length);
        for(;i < this.stars.length; i++) {
            this.stars[i].off();
            if (setSave) this.stars[i].save = false;
        }
    },
    _click: function(index) {
        //console.log('click '+index);
        //console.log('previous current index = '+this.currentIndex);
        this._setStars(index, true);
        this.currentIndex = index;
        this.submitionField.value = index;
    },
    _initializeOptions: function(options) {
        this.imagePath = this._getOption('imagePath', options);
        this.baseImageName = this._getOption('baseImageName', options);
        this.baseImageName = this.imagePath+'/'+this.baseImageName;
        this.imageType = this._getOption('imageType', options);
        this.halfStars = this._getOption('halfStars', options);
    },
    _getOption: function(name, options) {
        return ((typeof options == 'undefined' || typeof options[name] == 'undefined') ? defaultOptions[name] : options[name]);
    }
    
});
