(function($) {
	if(!document.defaultView || !document.defaultView.getComputedStyle){ // IE6-IE8
		var oldCurCSS = jQuery.curCSS;
		jQuery.curCSS = function(elem, name, force){
			if(name === 'background-position'){
				name = 'backgroundPosition';
			}
			if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ]){
				return oldCurCSS.apply(this, arguments);
			}
			var style = elem.style;
			if ( !force && style && style[ name ] ){
				return style[ name ];
			}
			return oldCurCSS(elem, 'backgroundPositionX', force) +' '+ oldCurCSS(elem, 'backgroundPositionY', force);
		};
	}
	
	var oldAnim = $.fn.animate;
	$.fn.animate = function(prop){
		if('background-position' in prop){
			prop.backgroundPosition = prop['background-position'];
			delete prop['background-position'];
		}
		if('backgroundPosition' in prop){
			prop.backgroundPosition = '('+ prop.backgroundPosition;
		}
		return oldAnim.apply(this, arguments);
	};
	
	function toArray(strg){
		strg = strg.replace(/left|top/g,'0px');
		strg = strg.replace(/right|bottom/g,'100%');
		strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
		var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
		return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
	}
	
	$.fx.step. backgroundPosition = function(fx) {
		if (!fx.bgPosReady) {
			var start = $.curCSS(fx.elem,'backgroundPosition');
			
			if(!start){//FF2 no inline-style fallback
				start = '0px 0px';
			}
			
			start = toArray(start);
			
			fx.start = [start[0],start[2]];
			
			var end = toArray(fx.options.curAnim.backgroundPosition);
			fx.end = [end[0],end[2]];
			
			fx.unit = [end[1],end[3]];
			fx.bgPosReady = true;
		}
		//return;
		var nowPosX = [];
		nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
		nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];           
		fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

	};
})(jQuery);

(function($) {
    var userAgent = navigator.userAgent.toLowerCase();

    $.browser = {
        version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
        safari: /webkit/.test( userAgent ),
        opera: /opera/.test( userAgent ),
        msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
        mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
    };

})(jQuery);

$.extend(Function.prototype, {
    use: function() {
		var method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
		return function() {
			return method.apply(object, args.concat(Array.prototype.slice.call(arguments)));
		}
    },
    useEL: function() {
        var method = this, args = Array.prototype.slice.call(arguments), object = args.shift();
        return function(event) {
            return method.apply(object, [event || window.event].concat(Array.prototype.slice.call(arguments)));
        }
    }
});

$.extend($.Event.prototype, {
    stop: function() {
        this.stopPropagation();
        this.preventDefault();
    }
});

/**
 * Controller
 * Manages the entire application (for the most part)
 */
var Controller = function() {
    this.els = {
        wishForm: $(Controller.selectors.wishForm),
        updateForm: $(Controller.selectors.updateForm),
        shareForm: $(Controller.selectors.shareForm),
        intro: $(Controller.selectors.intro),
        introClose: $(Controller.selectors.introClose),
        wishBtn: $(Controller.selectors.wishBtn),
        updateBtn: $(Controller.selectors.updateBtn)
    };
    
    this.Wish = [];
    
    this.wishForm = new Form(this.els.wishForm, true);

    this.stage = new Stage();
    this.wishes = [];
    
    this.stage.load();
 
    this.iteration = 0;

    if(window.location.hash != '') {
        var id = window.location.hash.match(/id=(\d+)/);

        this.getLoadWish(id[1])
        
    } else {
        this.getWishes();
        this.startTimer();
    }
    
    $(document).bind('error', this.alertError.useEL(this));
        
    $(document).bind('wish:add', function(event, event2, data) {
        var data = data[0];
        event.data = {
            id: data['data[Wish][id]'],
            i: 0,
            force: true,
            star: data['data[Wish][star]'],
            message: data['data[Wish][message]'],
            to_name: data['data[Wish][to_name]'],
            from_name: data['data[Wish][from_name]']
        }
        this.addWish(event); 
    }.useEL(this));
};
$.extend(Controller.prototype, {
    getLoadWish: function(id) {
        var self = this;
        $.getJSON('/wishes/view/' + id + '.json', '', function(data, status) {
            switch(status) {
                case 'success':
                    var i = 1;
                    $(data).each(function() {
                        this.Wish.i = i;
                        this.Wish.force = true;
                        self.addWish({ data: this.Wish })
                        i++;
                    });
                break;
            }
        });
        setTimeout(function() {
            this.getWishes();
            this.startTimer();
        }.use(this), 500);
    },
    getWishes: function() {
        var self = this;
        $.getJSON('/wishes/random.json', '', function(data, status) {
            switch(status) {
                case 'success':
                    if(this.iteration++ % 2) {
                        self.removeWishes(40);
                    } else {
                        self.removeWishes(50);
                    }
                    
                    var i = 1;
                    $(data).each(function() {
                        this.Wish.i = i;
                        self.addWish({ data: this.Wish })
                        i++;
                    });
                break;
            }
        });
    },
    startTimer: function() {
        if(this.interval || !!this.interval) { return; }
        this.interval = setInterval(function() {
            this.getWishes();
        }.use(this), 60000);
    },
    stopTimer: function() {
        clearInterval(this.interval);
        this.interval = false;
    },
    removeWishes: function(num) {
        while(num--) {
            if(this.wishes[num]) {
                this.wishes[num].hide(function() { 
                    this.wishes.shift(); 
                }.use(this));
            }
        }
    },
    addWish: function(event) {
        var wish = event.data;
        this.wishes.push(
            new Wish(wish.id, wish.star, wish.message, wish.to_name, wish.from_name, wish.i, wish.force)
        );
    },
    alertError: function(event, event2, message) {
        new ErrorHandler(message);
    }
});
$.extend(Controller, {
    selectors: {
        wishForm: '#wishForm',
        shareForm: '#shareForm',
        updateForm: '#updateBox',
        intro: '#intro',
        introClose: '#intro .close',
        wishBtn: '#intro .wishForm, #sendToFriend',
        updateBtn: '.btn.link.updates',
        wishClose: '#wishForm .close'
    },
    init: function() {
        Controller.instance = new Controller();
    }
});


var ErrorHandler = function() {

    //this.els = {
    //    overlay: $(ErrorHandler.selectors.overlay),
    //    container: $(ErrorHandler.selectors.container)
    //}
    //$.extend(this.els, {
    //    header: this.els.container.find(ErrorHandler.selectors.header).text(this.message.header),
    //    message: this.els.container.find(ErrorHandler.selectors.message).text(this.message.message),
    //    close: this.els.container.find(ErrorHandler.selectors.closeBtn).text(this.message.confirm)
    //});

    //this.els.close.bind('click', this.hide.useEL(this));
    //
    //this.show();
};
$.extend(ErrorHandler.prototype, {
    returnErrors: function(errors) {
        alert(errors.join('\n'))
    },
    setPosition: function() {
        var leftCenter = Math.round(($(window).width()/2)-(this.els.container.width()/2));
        var topCenter = Math.round(($(window).height()/2)-(this.els.container.height()/2));
        
        this.els.container.css({ 'top': topCenter+'px', 'left': leftCenter+'px' });
    },
    show: function() {
        this.setPosition();
        
        this.els.overlay.show().css({'opacity': 0}).animate({ 'opacity': 0.6 }, 500);
   
        this.els.container.fadeIn(500);
    },
    hide: function(event) {
        if(event) { event.stop(); }
        
        this.els.overlay.animate({ 'css': 0 }, 500, function() {
            this.els.overlay.hide();
        }.use(this));
        
        this.els.container.fadeOut(500);
    }
});
$.extend(ErrorHandler, {
    selectors: {
        overlay: '#overlay',
        container: '#errorBox',
        header: 'h2',
        message: 'p',
        closeBtn: '.btn'
    }
});


/**
 * Generic Form Class
 * Controls positioning, hiding and showing forms.
 */
var Form = function() {
    this.els = {
        container: $(Form.selectors.container)
    };
    
    $.extend(this.els, {
        inputs: {
            to: this.els.container.find(Form.selectors.inputs.to),
            toEmail: this.els.container.find(Form.selectors.inputs.toEmail),
            from: this.els.container.find(Form.selectors.inputs.from),
            fromEmail: this.els.container.find(Form.selectors.inputs.fromEmail),
            message: this.els.container.find(Form.selectors.inputs.message)
        },
        iconSelector: this.els.container.find(Form.selectors.iconSelector),
        overlay: this.els.container.find(Form.selectors.overlay),
        successMessage: this.els.container.find(Form.selectors.successMessage),
        errorMessage: this.els.container.find(Form.selectors.errorMessage),
        wishform: $(Form.selectors.wishform),
        wishsent: $(Form.selectors.wishsent),
        sentname: $(Form.selectors.sentname),
        sendanother: $(Form.selectors.sendanother)
    });
    
    this.els.successMessage.bind('click', this.resetForm.useEL(this));
    this.els.overlay.bind('click', this.resetForm.useEL(this));

    if(this.els.iconSelector.length) {
        this.iconSelector = new IconSelector();
    }

    this.els.container.bind('submit', this.submit.useEL(this));
    
    this.els.sendanother.bind('click', this.resetForm.useEL(this));
};
$.extend(Form.prototype, {
    updatePreview: function(event) {
        var newTo = this.els.inputs.to.val() || '[to]';
        this.els.preview.to.text(newTo);
        var newFrom = this.els.inputs.from.val() || '[from]';
        this.els.preview.from.text(newFrom);
        this.els.preview.event.text($(this.els.inputs.event.find('option')[this.els.inputs.event.val()-1]).text());
        this.els.preview.outcome.text($(this.els.inputs.outcome.find('option')[this.els.inputs.outcome.val()-1]).text() + '.');
        //this.els.icon.attr('src', Wish.outcomeMappings[this.els.inputs.outcome.val()-1].icon);
    },
    submit: function(event) {
        event.preventDefault();
        event.stopPropagation();
        
        var postData = this.els.container.serialize();
        
        $.ajax({
            url: this.els.container.attr('action') + '.json',
            data: postData,
            type: 'post',
            dataType: 'json',
            success: function(data) {
                if (!data.Success) {
                    for(var error in data.Validation) {
                        var $field = $('#Wish' + this.transposeFieldName(error)).parent('div');
                        if (!$field.hasClass('error')) {
                            $field.addClass('error').append('<p class="error-message">' + data.Validation[error] + '</p>');
                        }
                    }
                } else {
                    var data = {};
                    $(this.els.container.serializeArray()).each(function() {
                        data[this.name] = this.value;
                    });
                    this.showMessage();
                    $(document).trigger('wish:add', [[data]]);
                }
            }.use(this),
            error: function(data) {
                this.showMessage('error');
            }.use(this)
        });
    },
    showMessage: function() {
        this.els.sentname.text(this.els.inputs.to.val());
        this.els.wishform.slideUp(500, function() {
            this.els.wishsent.slideDown(500);
        }.use(this));
    },
    resetForm: function() {
        $.each(this.els.inputs, function(i) {
            $(this).val('');
        });
        
        this.els.wishsent.slideUp(500, function() {
            this.els.wishform.slideDown(500);
        }.use(this));
    },
    transposeFieldName: function(str) {
        return (str+'').replace('_', ' ').replace(/^(.)|\s(.)/g, function ( $1 ) { return $1.toUpperCase( ); } ).replace(' ', '');
    }
});
$.extend(Form, {
    selectors: {
        container: '#WishAddForm',
        inputs: {
            to: '#WishToName',
            toEmail: '#WishToEmail',
            from: '#WishFromName',
            fromEmail: '#WishFromEmail',
            message: '#WishMessage'
        },
        iconSelector: '#iconSelector',
        overlay: '#overlay',
        successMessage: '#successMessage',
        errorMessage: '#errorMessage',
        wishform: '.form',
        wishsent: '.sent',
        sentname: '.name',
        sendanother: '#sendanother'
    },
    strings: {
        submitError: {
            header: 'Error sending message',
            message: 'Please fill in all form fields and make sure they are correct.',
            confirm: 'Double Check'
        }
    },
    init: function() {
        Form.instance = new Form();
    }
});

/**
 * Image Preloader
 * Accepts a single or array of image source strings, preloads them and fires events.
 */
var Preloader = function(overlay) {
    this.cache = [];
    this.loading = false;
    
    if(overlay) {
        this.els = {
            overlay: $(Preloader.selectors.overlay),
            container: $(Preloader.selectors.loadingBox),
            stage: $(Preloader.selectors.stage)
        };
        
        $(document).bind('stage:ready', this.hide.useEL(this));
        
        this.show();
    }
};
$.extend(Preloader.prototype, {
   _load: function(source) {
       //if($.inArray(source, this.cache)) {
       //    $(this).trigger('loaded');
       //    return;
       //}
       
       var image = new Image();
       
       image.onload = function() {
           this.cache.push(image.src);
           $(this).trigger('loaded');
       }.use(this);
       
       image.onerror = function() {
           $(document).trigger('error', {image: source});
       }.use(this);
       
       this.loading = true;
       
       $(this).trigger('loading', {image: source});
       
       image.src = source;
   },
   load: function(sources) {
       var sources = $.makeArray(sources);
              
       var preCacheLength = this.cache.length;
       var l = sources.length;
              
       $(this).bind('loaded', function(event) {
           if(sources.length+preCacheLength == this.cache.length) {
               $(this).trigger('complete');
           }
       }.useEL(this));
       
       //$(this).bind('error', function(event) {
       //    $(document).trigger('error', {message: Preloader.strings.error})
       //}.useEL(this));
       
       while(l--) {
           this._load(sources[l]);
       }
   },
   setPosition: function() {
       var leftCenter = Math.round((this.els.stage.width()/2)-(this.els.container.width()/2));
       var topCenter = Math.round((this.els.stage.height()/2)-(this.els.container.height()/2));
       
       this.els.container.css({ 'top': topCenter+'px', 'left': leftCenter+'px' });
   },
   show: function() {
       //this.els.overlay.show();
       this.setPosition();
       this.els.container.show();
   },
   hide: function() {
       setTimeout(function() {
           //this.els.overlay.fadeOut(2000)
           this.els.container.fadeOut(2000)
       }.use(this), Preloader.minTimeout);
   }
});
$.extend(Preloader, {
    strings: {
        error: 'Error loading images. Please reload this page to try again.'
    },
    selectors: {
        overlay: '#overlay',
        loadingBox: '#loadingBox',
        stage: '#stagecontainer' 
    },
    minTimeout: 1000,
    init: function() {
        Preloader.instance = new Preloader(true);
    }
});

/**
 * Icon Selector
 */
var IconSelector = function(el) {
    this.els = {
        container: $(el),
        input: $(IconSelector.selectors.input)
    };
    $.extend(this.els, {
        preview: this.els.container.find(IconSelector.selectors.preview),
        list: this.els.container.find(IconSelector.selectors.list)
    });
    
    this.setRandom();
    
    this.els.preview.bind('click', this.preload.useEL(this));
};
$.extend(IconSelector.prototype, {
    preload: function(event) {
        var event = (event) ? event : null;
        if(event) { event.stop(); }
        if(this.els.list.find('img').length) { this.showSelector(event); return; }
        var loader = new Preloader();
        $(loader).bind('complete', function() {
            var self = this;
            $(IconSelector.icons).each(function(i) {
                self.els.list.append('<img src="' + this + '" alt="" longdesc="' + i +'" />');
            });
            this.els.list.find('img').bind('click', this.selectIcon.useEL(this));
            this.showSelector(event);
        }.useEL(this));
        loader.load(IconSelector.icons);
    },
    showSelector: function(event) {
        if(event) { event.stop(); }
        this.els.list.show(300);
    },
    hideSelector: function(event) {
        if(event) { event.stop(); }
        this.els.list.hide(200);
    },
    selectIcon: function(event) {
        if(event) { event.stop(); }
        this.setIcon($(event.target).attr('src'), $(event.target).attr('longdesc'));
        this.hideSelector();
    },
    setIcon: function(src, val) {
        this.els.preview.html('<img src="' + src + '" alt="" />');
        this.els.input.attr('value', val);
    },
    setRandom: function() {
        var length = IconSelector.icons.length;
        this.key = Math.floor(Math.random()*length);

        var loader = new Preloader();
        
        $(loader).bind('complete', function() {
            this.setIcon(IconSelector.icons[this.key], this.key);
        }.useEL(this));
        
        loader.load(IconSelector.icons[this.key]);
    }
});
$.extend(IconSelector, {
    icons: [
        '/img/heart-r-1.png',
        '/img/heart-pu-1.png',
        '/img/heart-b-1.png',
        '/img/heart-g-1.png',
        '/img/heart-o-1.png',
        '/img/heart-p-1.png'
    ],
    selectors: {
        preview: '.preview',
        input: '#WishStar',
        list: '.iconList'
    }
});

/**
 * Wish
 * Each instance of a wish from the database
 * @param id        {number}    Used to differentiate elements by HTML ID attribute.
 * @param icon      {string}
 * @param message   {string}
 * @param toName    {string}
 * @param fromName  {string}
 * @param loadNum   {number}    Used to determine how long until the icon will fade in.
 */
var Wish = function(id, star, message, toName, fromName, loadNum, force) {
    var now = new Date();
    this.origID = id;
    this.id = id+now.valueOf();
    this.container = $(Wish.selectors.container);
    this.starId = star;
    
    var rot = Math.floor(Math.random() * 3);
    if (rot == 3) { rot = 2; }
    
    this.star = Wish.stars[star][rot];
    this.message = message;
    this.names = { to: toName, from: fromName };
    this.loadNum = loadNum;
    this.forceCenter = force;
    //this.icon = Wish.outcomeMappings[this.outcome].icon;
    
    this.load();
};
$.extend(Wish.prototype, {
    load: function() {
        var p = new Preloader();
        
        $(p).bind('complete', this.show.useEL(this));

        p.load(this.star);
    },
    show: function() {
        var image = new Image();
        image.src = this.star;
        offset = image.width;
        wishclass = Math.round(this.id % 6)
        image = $('<div id="wish' + this.id + '" class="wish icon' + wishclass + '"><span style="background-image: url(' + this.star + ')"></span></div>').find('span').fixPNG().end();        
        
        var location = (!this.forceCenter) ? Controller.instance.stage.getRandomLocation(offset) : Controller.instance.stage.getCenter(offset);
        
        setTimeout(function() {
            this.container.append(image);
            
            this.el = $('#wish'+this.id).css({ top: location.top+'px', left: location.left+'px' }).hide().fadeIn(1000, function() {
                if(this.forceCenter) {
                    this.toggleInfoWindow();
                }
            }.use(this));
            
            this.el.bind('click', this.toggleInfoWindow.useEL(this))
                   .bind('mouseover', this.hover.useEL(this))
                   .bind('mouseout', this.hover.useEL(this));
        }.use(this), this.loadNum * 1000);
        
    },
    hide: function(callback) {
        var callback = (callback) ? callback : function() {};
        if(this.infoWindow && this.infoWindow.visible) { return; } else {
            if(!this.el) {
                return;
            }
            setTimeout(function() {
                if(this.infoWindow) { this.infoWindow.kill(); }
                
                function endAnimation() {
                    this.el.remove();
                    callback();
                }
                
                this.el.fadeOut(500, endAnimation.use(this));
                
            }.use(this), this.loadNum * 800);
        }
    },
    toggleInfoWindow: function() {
        if(!this.infoWindow) { 
            var left = this.el.css('left').replace('px', '');
            var top = this.el.css('top').replace('px', '');
            this.infoWindow = new InfoWindow({
                topOffset: top, leftOffset: left, 
                width: this.el.width(), height: this.el.height()
            }, {id: this.id, origID: this.origID, message: this.message, names: this.names, starId: this.starId}); 
        }
        
        this.infoWindow.toggle();
    },
    hover: function() {
        this.el.toggleClass('hover');
    }
});
$.extend(Wish, {
    selectors: {
        container: '#wishes'
    },
    stars: [
        [
            '/img/heart-r-1.png',
            '/img/heart-r-2.png',
            '/img/heart-r-3.png',
        ],
        [
            '/img/heart-pu-1.png',
            '/img/heart-pu-2.png',
            '/img/heart-pu-3.png',
        ],
        [
            '/img/heart-b-1.png',
            '/img/heart-b-2.png',
            '/img/heart-b-3.png',
        ],
        [
            '/img/heart-g-1.png',
            '/img/heart-g-2.png',
            '/img/heart-g-3.png',
        ],
        [
            '/img/heart-o-1.png',
            '/img/heart-o-2.png',
            '/img/heart-o-3.png',
        ],
        [
            '/img/heart-p-1.png',
            '/img/heart-p-2.png',
            '/img/heart-p-3.png',
        ]
    ]
});

/**
 * InfoWindow
 */
var InfoWindow = function(dimensions, data) {
    this.data = data;
    this.dimensions = dimensions;
    this.els = {
        container: $(InfoWindow.selectors.container).clone().attr('id', 'wish'+this.data.id).hide().appendTo(Stage.selectors.scrollElement)
    };
    $.extend(this.els, {
        content: this.els.container.find(InfoWindow.selectors.content),
        closeBtn: this.els.container.find(InfoWindow.selectors.closeBtn),
        sendBtn: this.els.container.find(InfoWindow.selectors.sendBtn),
        nameTo: this.els.container.find(InfoWindow.selectors.nameTo),
        nameFrom: this.els.container.find(InfoWindow.selectors.nameFrom),
        star: this.els.container.find(InfoWindow.selectors.star),
        message: this.els.container.find(InfoWindow.selectors.message),
        scrollElement: $(InfoWindow.selectors.stage)
    });

    this.position = dimensions;
    this.visible = false;
    this.populateData();
};
$.extend(InfoWindow.prototype, {
    toggle: function() {
        if(!this.visible) {
            this.show();
            //if(pageTracker) {
            //    pageTracker._trackPageview('/wishes/view/'+this.data.origID);
            //}
        } else {
            this.hide();
        }
    },
    setPosition: function() {
        var topOffset = parseInt(this.dimensions.topOffset, 10) + this.dimensions.height - 60;
        var leftOffset = parseInt(this.dimensions.leftOffset, 10) - this.els.scrollElement.scrollLeft();

        if(this.els.container.outerHeight()+topOffset >= this.els.scrollElement.scrollTop()+$(window).height()) {
            topOffset = topOffset-this.els.container.outerHeight()+this.dimensions.height;
        }
        
        if(this.els.container.outerWidth()+leftOffset >= this.els.scrollElement.scrollLeft()+$(window).width()) {
            leftOffset = leftOffset-this.els.container.outerWidth()+this.dimensions.width;
        }
        
        this.els.container.css({ left: leftOffset+'px', top: topOffset+'px' });
    },
    populateData: function() {
        this.els.star.attr('src', InfoWindow.stars[this.data.starId]);
        this.els.message.html(this.data.message);
        this.els.nameTo.html(this.data.names.to);
        this.els.nameFrom.html(this.data.names.from);
        this.els.message.attr('value', this.data.message);
    },
    show: function() {
        $(document).trigger('showWindow');
        this.setPosition();
        
        var callback = function() {
            this.visible = true;
            $(document).bind('showWindow', this.hide.useEL(this));
            this.els.closeBtn.bind('click', this.hide.useEL(this));
        }.use(this);
        
        this.els.container.fadeIn(500, callback.use(this));
        
    },
    hide: function(event) {
        if(event) { event.stop(); }
        
        var callback = function() {
            this.els.container.hide();
            this.visible = false;
        }.use(this);
        
        this.els.container.fadeOut(500, callback.use(this));
    },
    kill: function() {
        if(!this.visible) {
            this.els.container.remove();
        } else {
            return false;
        }
    }
});
$.extend(InfoWindow, {
    stars: [
        '/img/heart-r-1.png',
        '/img/heart-pu-1.png',
        '/img/heart-b-1.png',
        '/img/heart-g-1.png',
        '/img/heart-o-1.png',
        '/img/heart-p-1.png'
    ],
    selectors: {
        container: '#infoWindow',
        content: '.content',
        closeBtn: '.close',
        sendBtn: '.send',
        nameTo: '.to',
        nameFrom: '.from',
        star: '.star',
        message: '.message',
        stage: '#stagecontainer'
    }
})

/**
 * Stage
 * Controls the parallax effects
 */
var Stage = function() {
    this.els = {
        container: $(Stage.selectors.container),
        leftBtn: $(Stage.selectors.leftBtn),
        rightBtn: $(Stage.selectors.rightBtn),
        scrollElement: $(Stage.selectors.scrollElement),
        wishContainer: $(Stage.selectors.wishContainer)
    };
    
    this.layers = [];
    
    this.setSize();
    
    this.els.leftBtn.bind('click', this.panLeft.useEL(this));
    this.els.rightBtn.bind('click', this.panRight.useEL(this));
    $(document).bind('keydown', this.keyHandler.useEL(this));
    
    $(document).bind('form:show', this.disablePanButtons.useEL(this));
    $(document).bind('form:hide', this.enablePanButtons.useEL(this));
};
$.extend(Stage.prototype, {
    keyHandler: function(event) {
        switch(event.keyCode) {
            case 37:
                if(this.ablePanLeft) {
                    this.panLeft(event);
                }
            break;
            case 39:
                if(this.ablePanRight) {
                    this.panRight(event);
                }
            break;
        }
    },
    load: function() {
        $(document).trigger('stage:ready');
        
        //var loader = new Preloader();
        //var sources = $.map(Stage.layers, function(i) { return i.src; });
        //
        //$(loader).bind('complete', this.appendToEls.useEL(this));
        //
        //loader.load(sources);
    },
    /*
    appendToEls: function() {
        var self = this;
        $(Stage.layers).each(function() {
            self.els.container.append('<div id="'+this.id+'" style="background-image: url('+this.src+');"></div>');
            //$('#'+this.id).css({ backgroundPosition: '(0px 0px)'});
            self.layers.push(this);
        });
        $(document).trigger('stage:ready');
    },
    */
    show: function() {
        this.els.container.fadeIn(500);
    },
    getRandomLocation: function(offset) {
        var offset = (offset) ? offset : 0;
        var width = this.els.wishContainer.width();
        var height = this.els.wishContainer.height();
        
        var leftOffset = Math.round(width*(Math.random()));
        leftOffset = (leftOffset+(offset*2) > width) ? leftOffset-(offset) : leftOffset;
        leftOffset = (leftOffset-offset < 0) ? leftOffset+offset : leftOffset;
        leftOffset = (leftOffset < Stage.iconPadding.left) ? Stage.iconPadding.left+leftOffset : leftOffset;
        leftOffset = (leftOffset > width+Stage.iconPadding.right) ? leftOffset-Stage.iconPadding.right : leftOffset;
        
        var topOffset = Math.round(height*(Math.random()));
        topOffset = (topOffset+offset > height) ? topOffset-(offset) : topOffset;
        topOffset = (topOffset < 0) ? topOffset+offset : topOffset;
        topOffset = (topOffset < Stage.iconPadding.top) ? Stage.iconPadding.top+topOffset : topOffset;
        topOffset = (topOffset+offset+Stage.iconPadding.bottom >= height-Stage.iconPadding.bottom) ? topOffset - (height / 4) - Stage.iconPadding.bottom - offset : topOffset;
        
        return { left: leftOffset, top: topOffset };
    },
    getCenter: function(offset) {
        var windowCenterLeft = Math.round(this.els.scrollElement.width()/2)+this.els.scrollElement.scrollLeft()-Math.round(offset/2);
        var windowCenterTop  = Math.round(this.els.scrollElement.height()/2)+this.els.scrollElement.scrollTop()-offset;
        
        return { left: windowCenterLeft, top: windowCenterTop };
    },
    setSize: function(event) {
        //if($.browser.msie) { 
            this.disablePanButtons();
        //} else {
        //    this.els.container.width(this.els.container.width() * Stage.stops);
        //    this.togglePanButtons();
        //}
    },
    panLeft: function(event) {
        event.stop();
        this.els.leftBtn.unbind('click').bind('click', function(event) { event.stop(); });
        var leftPos = Math.floor(this.els.scrollElement.scrollLeft()-($(window).width()/2));
        this.pan(leftPos);
    },
    panRight: function(event) {
        event.stop();
        this.els.rightBtn.unbind('click').bind('click', function(event) { event.stop(); });
        var leftPos = Math.ceil(this.els.scrollElement.scrollLeft()+($(window).width()/2))-1;
        this.pan(leftPos);
    },
    pan: function(leftPos) {
        $(document).trigger('showWindow');
        this.scrollLeft = this.els.scrollElement.scrollLeft();
        this.panTimer = setInterval(function() {
            this.parallax();
        }.use(this), 50);
        this.els.scrollElement.animate({ scrollLeft: leftPos+'px' }, 2000, 'easeInOutSine', function() {
            this.togglePanButtons();
            clearInterval(this.panTimer);
        }.use(this));
    },
    disablePanButtons: function(override) {
        if(this.els.scrollElement.scrollLeft()+$(window).width() >= this.els.container.width()-($(window).width()/3) || override) {
            this.ablePanRight = false;
            if($.support.opacity)  {
                this.els.rightBtn.fadeOut(500);
            } else {
                this.els.rightBtn.hide();
            }
        }
        if(this.els.scrollElement.scrollLeft() <= 0 || override) {
            this.ablePanLeft = false;
            if($.support.opacity)  {
                this.els.leftBtn.fadeOut(500);
            } else {
                this.els.leftBtn.hide();
            }
        }
    },
    enablePanButtons: function() {
        if(this.els.scrollElement.scrollLeft()+$(window).width() < this.els.container.width()-($(window).width()/3)) {
            this.ablePanRight = true;
            if($.support.opacity)  {
                this.els.rightBtn.fadeIn(500).bind('click', this.panRight.useEL(this));
            } else {
                this.els.rightBtn.show().bind('click', this.panRight.useEL(this));
            }
        }
        if(this.els.scrollElement.scrollLeft() > 0) {
            this.ablePanLeft = true;
            if($.support.opacity)  {
                this.els.leftBtn.fadeIn(500).bind('click', this.panLeft.useEL(this));
            } else {
                this.els.leftBtn.show().bind('click', this.panLeft.useEL(this));
            }
        }
    },
    togglePanButtons: function() {
        this.disablePanButtons();
        this.enablePanButtons();
    },
    parallax: function() {
        var scrollLeft = this.els.scrollElement.scrollLeft();
        var diff = this.scrollLeft-scrollLeft;
        $(this.layers).each(function() {
            var el = $('#'+this.id);

            var leftPos = (el.css('backgroundPosition')) ? parseInt(el.css('backgroundPosition').split(' ')[0], 10) : Number(0);
            $('#'+this.id).css({'backgroundPosition': (Math.ceil(diff*this.speed)-diff)+leftPos+'px 0px' });
        });
        this.scrollLeft = this.els.scrollElement.scrollLeft();
    }
});
$.extend(Stage, {
    layers: [
   ],
    selectors: {
        container: '#stage',
        leftBtn: '#stageLeft',
        rightBtn: '#stageRight',
        scrollElement: '#stagecontainer',
        wishContainer: '#wishes'
    },
    iconPadding: {
        top: 10,
        right: 10,
        bottom: 30,
        left: 10
    },
    stops: 2
});

$.fn.fixPNG = function() {
	return this.each(function () {
	    if(!$.support.opacity) {
    		var image = $(this).css('backgroundImage');

    		if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
    			image = RegExp.$1;
    			$(this).css({
    				'backgroundImage': 'none',
    				'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=" + ($(this).css('backgroundRepeat') == 'no-repeat' ? 'crop' : 'scale') + ", src='" + image + "')"
    			}).each(function () {
    				var position = $(this).css('position');
    				if (position != 'absolute' && position != 'relative')
    					$(this).css('position', 'relative');
    			});
    		}
	    }
	});
};

$(document).ready(function() {
    if ($.browser.msie) {
        Stage.layers = [
            { id: 'background', src: '/css/images/background-ie.jpg', speed: 1.5 },
            { id: 'moon', src: '/css/images/moon.jpg', speed: 1.5 }
        ]
    }

    $('#WishStar').after('<div id="iconSelector"><a href="#iconList" class="preview"></a><div class="iconList"></div></div>');
    Preloader.init();
    Controller.init();
    
    $('.submit').attr('value', '');
});