﻿/**
 * FormValidation - Fancy validation with mootools
 * - Needs an array with the elements to be validated
 * - Bases on Mootools.v1.1 
 * 
 * @example
 * 
 *	var validation = new Validation($$('.required'));
 * 
 * @version		1.0rc0
 * 
 * @see			Events, Options
 * 
 * @author		Jasper Steenweg <jasper [at] metrostation.net>
 * @copyright	2007 Author
 *
 *
 */
var Validation = new Class({

    getOptions: function(){
        return {
	        onShow: function(message){	       
	            message.setStyle('visibility', 'visible');
	        },
	        onHide: function(message){
	            message.setStyle('visibility', 'hidden');
	        },
	        maxWidth: 200,
	        showDelay: 100,
	        hideDelay: 100,
	        borderColor: '#FF0000',
	        className: 'm-error-message',
	        offsets: {'x': 3, 'y': -3},
            sizeOffset: { 'x': false, 'y': true },
            fixed: true
	    };
    },

    initialize: function(elements, options){        
        this.setOptions(this.getOptions(), options);
	    this.message = new Element('div').addClass(this.options.className).setStyles({
	        'position': 'absolute',	        
	        'top': '0',
	        'left': '0',
	        'max-width': this.options.maxWidth,
	        'visibility': 'hidden'
	    }).injectInside(document.body);	  
	    this.wrapper = new Element('div').injectInside(this.message);  
	    this.valid = true;
	    $each(elements, function(el){	        
	        this.build($(el));
	    }, this);
	    if (this.options.initialize) this.options.initialize.call(this);
    },

    build: function(el){
        el.myTitle=false;
	    el.myText=el.getAttribute("message");
        el.originalBorder = el.getStyle('border');
	    el.addEvent('blur', function(event) { this.validate(el); }.bindWithEvent(this));
	    this.validate(el);
	    
    },

    start: function(el){
	    this.wrapper.setHTML('');	    
	    if (el.myText){
	        new Element('span').injectInside(
                new Element('div').addClass(this.options.className+'-text').injectInside(this.wrapper)
            ).setHTML(el.myText);
	    }
	    $clear(this.timer);
	    this.timer = this.show.delay(this.options.showDelay, this);
	},

    end: function(event){
	    $clear(this.timer);
	    this.timer = this.hide.delay(this.options.hideDelay, this);
	    event.stop();
    },
    
    validate: function(el) {        
        var oFx = new Fx.Style(el, 'border-color',{duration:500,transition: Fx.Transitions.Quad});
        
        if (!el.value) {        
            switch (el.getTag()) {
                case "input":
                    oFx.start('#000000', this.options.borderColor);
                    el.addEvent('focus', function(event) { this.locate(el); this.start(el); this.show(); }.bindWithEvent(this));
	                el.addEvent('blur', this.end.bindWithEvent(this));
	                break;
	        }
	        
	        this.valid = false;
	    }
	    else
	    {
	        el.setStyle('border', el.originalBorder);
	    }
    },

    locate: function(el){

        // Locate where the event came from.  In our case:
        //  position is the upper left corner of the input that gained focus
        //  size is the size of the input that gained focus, in px
        var pos=el.getPosition();
		var size=el.getSize();

        // By default, position hint at top left corner of input,
        // and offset by our offset amounts.
        var left = pos['x'] + this.options.offsets['x'];
        var top = pos['y'] + this.options.offsets['y'];

        // If user specified that a sizeOffset should be used, additionally
        // offset the hint by the size of the control that gained focus
        if (this.options.sizeOffset['x']){ left = left + size['size']['x']; }
        if (this.options.sizeOffset['y']){ top = top + size['size']['y']; }

        // Assign the hint location        
        this.message.setStyle('left',  left + 'px');
        this.message.setStyle('top', top + 'px');
    },

    show: function(){        
        this.fireEvent('onShow', [this.message]);
    },

    hide: function(){
        this.fireEvent('onHide', [this.message]);
    }

});

Validation.implement(new Events);
Validation.implement(new Options);
