(function () {
    
    var G = Allthat.namespace('Allthat.GUI');
    /**
     * Bind event listeners to the mouseDown event to add to image buttons (like "save") ability to became "clicked"
     * @class MouseDown
     * @module GUI
     */
    G.MouseDown = new Class({
        Implements : Options,
        options : {
            targets : 'mousedown'
        },
        initialize : function () {
            // bind scope "this" to the methods
            this.boundedMouseOver = this.mouseOver.bind(this);
            this.boundedMouseOut = this.mouseOut.bind(this);
            this.boundedMouseDown = this.mouseDown.bind(this);
            this.boundedMouseUp = this.mouseUp.bind(this);
            
            this.body = $$('body')[0]; // remember reference to body - just to save few CPU cycles ;)
            
            this.body.addEvent('mousedown', this.boundedMouseDown);
            
            this.preloadImages();
        },
        /**
         * @method mouseOver
         */
        mouseOver : function(event) {
    		if (this.down) {
    			this.setDown();	
    		}
    	},
        /**
         * @method mouseOut
         */
        mouseOut : function(event) {
     		this.setUp();
     	},
     	
        /** 
         * check, if user clicks on the target with css class 'mouseover', remember that element and call setDown on that element
         * @method mouseDown
         */
        mouseDown : function(e) {
            var el = $(e.target);
            if (el.hasClass(this.options.targets)) {
                this.down = el;
                this.body.addEvent('mouseup', this.boundedMouseUp);
                this.down.addEvent('mouseover', this.boundedMouseOver);
                this.down.addEvent('mouseout', this.boundedMouseOut);
                this.setDown();
            }
    	},
        /**
         * Remove mouseup, mouseover, mouseout event listeners from the current element and call setUp method
         * @method mouseUp
         * @param event {Event} DOM event
         */
    	mouseUp : function(event) {
    	    this.body.removeEvent('mouseup', this.boundedMouseUp);
    		this.down.removeEvent('mouseover', this.boundedMouseOver);
    		this.down.removeEvent('mouseout', this.boundedMouseOut);

    		this.setUp();
    		this.down = null;
    	},
        /**
         * Emulate "clicked" effect on the image - actually, replace it's src
         * @method setDown
         */
    	setDown : function() {
    		var elem = this.down;
    		if (elem && elem.type=="image") {
    			var imgSrc = elem.getProperty('src'),
    			    lastIndex = imgSrc.lastIndexOf('.');
    			imgSrc = imgSrc.substring(0, lastIndex) + '_down' + imgSrc.substring(lastIndex, imgSrc.length);
    			elem.setProperty('src', imgSrc);
    		} else if (elem && elem.type=="submit"){
		        var imgSrc = elem.getStyle('background-image'),
    			    lastIndex = imgSrc.lastIndexOf('.');
                  
                        imgSrc = imgSrc.substring(0, lastIndex) + '_down' + imgSrc.substring(lastIndex, imgSrc.length);
    		        elem.setStyle('background-image', imgSrc);
                      
                }
    	},
        /**
         * Emulate end of the "click" to the image button - again, replace image's src
         * @method setUp
         */
    	setUp : function() {
    		var elem = this.down;
    		if (elem) {
                        if (elem.type=="submit"){
    			  var imgSrc = elem.getStyle('background-image');
    			  imgSrc = imgSrc.replace('_down', '');
		          elem.setStyle('background-image', imgSrc);
                        }else{
                          var imgSrc = elem.getProperty('src');
    			  imgSrc = imgSrc.replace('_down', '');
		          elem.setProperty('src', imgSrc);
                        }
    		}

    	},
    	/**
    	 * Preload images which we will need (like add2_down and such - to remove pause between mousedown and image displaying)
    	 * @method preloadImages
    	 */
    	preloadImages : function () {
    	    var t = new Element('div', {
    	        'styles' : {
    	            display: 'none',
    	            position: 'absolute',
    	            top: -10000,
    	            left: -10000
    	        }
    	    }), // create invisible div which should contain our images
            imageSources = ['/images/save_query_down.gif',
                            '/images/go_btn_down.jpg',
                            '/images/add2_down.jpg',
                            '/images/save_down.jpg'];

            imageSources.each(function (source) {
                i = new Element('img', {
    	            src : source
    	        });
    	        
    	        t.appendChild(i);  
            }, this);
            
             	    
    	    t.setStyle('display', 'block');
    	}
    });
    
})();

