/**
 * LNCFormValidation
 *
 * @version		1.0
 *
 * @license		Commercial license
 * @author		Jan Cinert <jan.cinert [at] gmail.com>
 * @copyright	Author
 */

function showAjaxIndicator( id ) {
  var img = new Element( 'img', { 'src': 'inc/app/local/lib/lnc/FormValidation/assets/spinner.gif' } );
  try {
    $( $pick( id, 'log_res') ).empty().adopt( img ).addClass('ajax-loading');
  } catch(e) {}
}

function hideAjaxIndicator( id ) {
  try {
    $( $pick( id, 'log_res') ).empty().removeClass('ajax-loading');
  } catch (e) {}
}

Object.toQueryString = Hash.toQueryString;

var XHR = new Class({

	Extends: Request,

	options: {
		update: false
	},

	initialize: function(url, options){
		this.parent(options);
		this.url = url;
	},

	request: function(data){
		return this.send(this.url, data || this.options.data);
	},

	send: function(url, data){
		if (!this.check(arguments.callee, url, data)) return this;
		return this.parent({url: url, data: data});
	},

	success: function(text, xml){
		text = this.processScripts(text);
		if (this.options.update) $(this.options.update).empty().set('html', text);
		this.onSuccess(text, xml);
	},
	
	failure: function(){
		this.fireEvent('failure', this.xhr);
	}

});

var Ajax = XHR;
var Json = JSON;
JSON.toString = JSON.encode;
JSON.evaluate = JSON.decode;

Element.implement({

	sendWithMerge: function(options, sender){
	  if( $defined(sender) ) {
	    sender.request( this.toQueryString() + ( $defined( options.data ) ? ('&' + Object.toQueryString( options.data )) : '' ) );
	    return sender;
	  }
	  else {
	    if( $defined( options.data ) ) {
	      options.data = this.toQueryString() + '&' + Object.toQueryString( options.data );
	    }
	    else {
	      options.data = this.toQueryString();
	    }
		  return new Ajax(this.getProperty('action'), $merge(options, {method: 'post'})).request();
	  }
	},
	
	getText: function(){
		return this.get('text');
	},

	setText: function(text){
		return this.set('text', text);
	},

	setHTML: function(){
		return this.set('html', arguments);
	},
	
	getHTML: function(){
		return this.get('html');
	},

	getTag: function(){
		return this.get('tag');
	}

});

var LNCFormValidation = new Class({
	initialize: function()
	{
		var forms = $$('form.form-validate');
		forms.each(function(form){this.attach( form ); }, this);
	},
	
	attach: function(form) {
	  form.addEvent('submit', this.onSubmit.bindWithEvent(this, [form]) );
	},

	onSubmit: function(ev, form) {
	  ev = new Event(ev).stop(); 
	  this.validate( form );
  },
  
  validate: function( form, submitTask, data ) {
    
    showAjaxIndicator();
    
    var data = data || {};
    if( $defined(form.validate) ) {
      data.validate = '1';
      if( $defined(submitTask) ) {
        data.task = submitTask;
      }
    }
    else {
      data.task = 'validate';
    }

    form.sendWithMerge({
      data: data,
      onComplete: function( responseText ) { this.onComplete( responseText, form, submitTask ) }.bind(this)
    });

  },
  
	onComplete: function( responseText, form, submitTask ) {
	  hideAjaxIndicator();
    if( !$defined( responseText ) ) return;

    try {
      
      if( responseText.indexOf( '###' ) != -1 ) {
        responseText = responseText.split( '###' )[1];
      }
      var obj = Json.evaluate( responseText );
    }catch (e) {}

    if($defined(obj)) {
      
      if( $type( obj ) == 'string' ) {
        window.location.href = obj;
        return;
      }
      
      this.errors = obj;
      var isValid = false;

      if( obj.length == 0 ) {
        new Fx.Scroll(window).toElement( document.body );
        isValid = true;
        form.getElements('.validation_message').each(
          function(item) {
            item.removeClass('success').removeClass('error').getElement('.validation_message_text').setText( '' );
          }
        );
        if( $defined(submitTask) ) {
          form.task.value = submitTask;
        }
        
        var ev = { cancel: false, target: form };
        this.fireEvent('onSubmit', ev);
        if( !ev.cancel ) {
          if (typeof form.onsubmit == "function") {
        		form.onsubmit();
        	}
        	var submit = form.getElement( 'input[type="submit"]' );
          if( submit ) {
            form.grab( new Element( 'input', { 'type': 'hidden', name: submit.getAttribute( 'name' ), 'value': submit.get( 'value' ) } ) );
          }
    
          form.submit();
        }
      }
      else {
        var topEl = null;
        var parent = form.getParent().getParent();
        form.getElements('.validation_message').each(
          function(item) {
            var name = item.title.replace('validation_message_', '');
            if( name && name in obj ) {
              if( $type( obj[name] ) == 'string' ) {
                
        			  item.addClass('error').removeClass('success').getElement('.validation_message_text').setText( obj[name] );
        			  delete( obj[name] );
              }
              else {
                item.addClass('error').removeClass('success').getElement('.validation_message_text').setText( '' );
              }
              
              if( topEl == null || item.getCoordinates( parent ).top < topEl ) {
                topEl = item.getCoordinates( parent ).top;
              }
              
      			}
      			else {
      			  item.addClass('success').removeClass('error').getElement('.validation_message_text').setText( '' );
      			}
          }
        );
        
        if( topEl ) {
          new Fx.Scroll(window).start( 0, topEl );
        }
        
        for( var i in obj ) {
          if( $type( obj[i] ) == 'array' ) {
            obj[i].each(
              function( errors, key ) {
                var heading = form.getElements('.validation_message_'+i)[key];

                if( isEmpty( errors ) ) {
                  heading.addClass('success').removeClass('error').getElement('.validation_message_text').setText( '' );
                }
                else {
                  heading.addClass('error').removeClass('success').getElement('.validation_message_text').setText( '' );
                  for( var name in errors ) {
                    var element = form.getElements('.validation_message_'+name)[key];
                    if( $defined( element ) ) {
                      element.addClass('error').removeClass('success').getElement('.validation_message_text').setText( errors[name] );
                    }
                  }
                }
            });
          }
        }
      }
      form.fireEvent('onValidationComplete', [isValid]);
    }
  }
});

LNCFormValidation.implement(new Events);

window.addEvent( 'domready', function(){
	document.formvalidator = new LNCFormValidation();
});