var errorMessage = {
  'customertype': 'Please select your customer type',
  'b_fname': 'Please enter your first name',
  'b_lname': 'Please enter your last name',
  'phone_night': 'Please enter a valid phone number',
  'email': 'Please enter a valid email address',
  'mv_username': 'Please enter a valid email address',
  'b_address1': 'Please enter the first line of your address',
  'b_city': 'Please enter your town/city',
  'b_state': 'Please enter your county',
  'b_zip': 'Please enter your postcode',
  'b_zip_mismatch': 'Sorry, that looks like a US Zipcode. We only deliver to addresses in the UK.',
  'fname': 'Please enter the delivery first name',
  'lname': 'Please enter the delivery last name',
  'address1': 'Please enter the first line of the delivery address',
  'city': 'Please enter the delivery town/city',
  'state': 'Please enter the delivery county',
  'zip': 'Please enter the delivery postcode',
  'zip_mismatch': 'Sorry, that looks like a US Zipcode. We only deliver to addresses in the UK.',
  'password_verify': 'Please re-enter your password',
	'password_verify_mismatch': 'The passwords entered do not match',
	'password_verify_length': 'Your password must be at least 6 characters',
  'card_holder_name': 'Please enter the name on your card',
  'mv_credit_card_number': 'Please enter a valid card number',
  'mv_credit_card_exp_month': 'Please select an expiry date',
  'mv_credit_card_cvv2': 'Please enter your security number',
  'project_id': 'Please enter a purchase order number',
  'password': 'Please enter a password',
  'billing_search_postcode': 'Please enter a Card Holders Details / Billing Address to continue',
  'delivery_search_postcode': 'Please enter a delivery address to continue',
  'feedbackname': 'Please enter your name',
  'ordernum': 'Please enter your order number',
  'phone': 'Please enter a phone number we can contact you on',
  'comments': 'Please enter the items and any other information',
  'mv_verify': 'Please re-enter your password',
	'mv_verify_mismatch': 'The passwords entered do not match', 
	'mv_verify_length': 'Your password must be at least 6 characters',
	'mv_password': 'Please enter a password',
	'mv_password_old': 'Please enter your old password',
	'printer_name': 'Please enter a memorable name',
	'printer_manufacturer': 'Please select a manufacturer',
	'printer_model': 'A model has not been selected',
	
	'organisation_name': 'Please enter an organisation name',
	'organisation_type': 'Please enter your type of business',
	'contact_name': 'Please enter a contact name for ordering',
	'accounts_contact_name': 'Please enter an accounts contact name',
	'full_address1': 'Please enter your full address',
	'postcode': 'Please enter a postcode',
	'telephone': 'Please enter a telephone number',
	'fax': 'Please enter a fax number',
	'cartridge_spending': 'Please enter roughly, how much per year you spend on printer cartridges',
	'credit_amount': 'Please enter the credit amount required'
};

var payment_methods = {
  'credit_card': 'card', 
  'cod': 'cod', 
  'postal': 'postal', 
  'online_check': 'online_check', 
  'purchase_order': 'po', 
  'amazon': 'amazon'
};

var newValidation;

var Validate = Class.create();
Validate.prototype = {
  
  initialize: function() {
    
    var th = this;
    
    // getting pages forms
    
    $$('form.validate').each(function(current_form) {
      
      // validation
      Element.observe(current_form,'submit',th.validate.bindAsEventListener(th,current_form));
      var elements = current_form.getElements();
      
      for( var i=0; i<elements.length; i++ ) {
    
        var item = elements[i];      
        
        if( item.hasClassName('validate') ) {
        
          Element.observe(item,'blur',th.check_item.bindAsEventListener(th,item,true,true));
          
          // validating all select dates
          if( item.hasClassName('date') ) {
          
            var select_elm = item;
            var select_siblings = select_elm.siblings();

            for( j=0; j<select_siblings.length; j++ ) {

              var select_item = select_siblings[j];
              if( select_item.type == 'select-one' ) {
                Element.observe(select_item,'blur',th.check_item.bindAsEventListener(th,select_elm,true,true));
              }

            }
          
          } 
          // validating all passwords
          if( item.hasClassName('password') ) {
          
            var passwords = current_form.getInputs('password');
            Element.observe(passwords[0],'blur',th.check_item.bindAsEventListener(th,item,true,true));
          
          }
          // validating hidden addresses
          if( item.hasClassName('postcode_search') ) {
          
            var address_line_1 = ( item.name == 'billing_search_postcode' ) ? $$('input[name=b_address1]') : $$('input[name=address1]');
            Element.observe(address_line_1[0],'blur',th.check_item.bindAsEventListener(th,item,true,true));            
             
          }
        }
    
      }
  
    });
    
  },
  
  validate: function(e,thisForm) {
    
    var th = this;
    
    // comment for double order
    if( $('placeorder') ) $('placeorder').disabled = true;
    
    var inputs = thisForm.getElements();
    var validates = true;
    th.first_element = true;
    
    inputs.each(function(item) {
      validates = th.check_item(th,item,validates,false,thisForm);
    });
    
    if( !validates ) {
      // set values for items
      if( $('save_if_fails') ) this.setFormValues(this.checkout_form);
      // comment for double order
      if( $('placeorder') ) $('placeorder').disabled = false;
      Event.stop(e);
    } else {
    
      // uncomment for double order
      /*if( $('placeorder') ) {
        Event.stop(e);
        newLightBox.create(undefined,'/ord/double_order.html');
      }*/
      
    }
    
  },
  
  check_item: function(e,item,validates,close_only,current_form) {
    
    var th = this;
    
    if( !current_form ) {
      $$('form.validate').each(function(f){
        if( item.descendantOf(f) ) current_form = f;
      });
    }
    
    var id = item.name.camelize();
    var validate_delivery = $('mv_same_billing') ? ( ( $('mv_same_billing').getValue() == '1' ) ? false : true ) : false;
    
    var payment_method = ( $('mv_order_profile') ) ? $('mv_order_profile').getValue() : undefined;
    if( payment_method == 'account_change' ) payment_method = undefined;
    var payment_method_class = payment_methods[payment_method];
    
    // checking payment method inputs only
    if( payment_method != undefined ) {
    
      if( item.hasClassName('validate') && item.hasClassName(payment_method_class)) {
        if( item.hasClassName('date') ) {
          var selects = item.siblings();
          var selects_validate = true;
          
          if( item.getValue().empty() ) selects_validate = false;
          
          for( var i=0; i<selects.length; i++ ) {
            var select_item = selects[i];
            
            if( select_item.type == 'select-one' ) {
              if( select_item.getValue().empty() ) selects_validate = false;
            }
          }
          
          if( !selects_validate ) {
            validates = th.show_message(item,validates,close_only);
          } else {
            this.close_message(id);
          }
          
        } else if( item.hasClassName('integer') ) {

          var value = item.getValue().replace(/ /g,'');
          var exp = /^\d+$/;
          
          if( !exp.test(value) ) {
            validates = th.show_message(item,validates,close_only);
          } else {
            this.close_message(id);
          }

        } else {
          validates = th.default_check(item,validates,close_only);
        }
      }
    
    } 
    // normal type of validation
    else {    
    
      if( item.hasClassName('validate') ) {
        
        // email check
        if( item.hasClassName('email') ) {
          
          var exp = /[\w\.%+-]+@[\w\.-]+\.\w{2,4}$/;

          if( item.getValue().empty() || !exp.test(item.getValue()) ) {
            validates = th.show_message(item,validates,close_only);
          } else {
            th.close_message(id);
          }
          
        }
        // password check
        else if( item.hasClassName('password') ) {
          
          var passwords = current_form.getInputs('password');

					var password = passwords[0].getValue();
					var verify_password = passwords[1].getValue();
					
					if( verify_password.empty() ) {
						validates = th.show_message(item,validates,close_only);
					} else if( password != verify_password ) {
            validates = th.show_message(item,validates,false,true);
          } else if( password.length < 6 || verify_password.length < 6 ) {
            validates = th.show_message(item,validates,false,false,true);
          } else {
            th.close_message(id);
          }
                    
        }
        // multi select date 
        else if( item.hasClassName('phone') ) {
          
          var value = item.getValue().replace(/ /g,'');
          var exp = /^\d{10,11}$/;
          
          if( !exp.test(value) ) {
            validates = th.show_message(item,validates,close_only);
          } else {
            th.close_message(id);
          }
          
        }
        // postcode
        else if( item.hasClassName('postcode_check') ) {
          
          var value = item.getValue().replace(/ /g,'');
          value = value.toUpperCase();
          
          var exp = /[A-Z]{1,2}[0-9R][0-9A-Z]?[0-9][ABD-HJLNP-UW-Z]{2}/;
          
          // check if empty
          if( item.getValue().empty() ) {
            if( validate_delivery && item.hasClassName('delivery') ) validates = th.show_message(item,validates,false);
            if( !item.hasClassName('delivery') ) validates = th.show_message(item,validates,false);
          }
          // check if non uk with separate delivery address
          else if( !exp.test(value) && validate_delivery && item.hasClassName('delivery') ) {
            validates = th.show_message(item,validates,false,true);
          }
          // check if non uk with the billing as delivery address
          else if( !exp.test(value) && !validate_delivery ) {
            validates = th.show_message(item,validates,false,true);
          }
          // else fine
          else {
            th.close_message(id);
          }
          
        }
        // number
        else if( item.hasClassName('integer') ) {
          
          var value = item.getValue().replace(/ /g,'');
          var exp = /^\d+$/;
          
          if( !exp.test(value) ) {
            validates = th.show_message(item,validates,close_only);
          } else {
            th.close_message(id);
          }
          
        }
        // multi address line 
        else if( item.hasClassName('postcode_search') ) {
          
          var billing = ( item.name == 'billing_search_postcode' ) ? true : false;
          var address_fields_display = ( billing ) ? $('card_holder_address').getStyle('display') : $('delivery_address').getStyle('display');
          
          if( billing ) {
            
            var address_line_1 = $$('input[name=b_address1]');
            if( address_line_1[0].getValue().empty() ) {
              if( address_fields_display == 'none' ) validates = th.show_message(item,validates,close_only);
            } else {
              this.close_message(id);
            }
            
          } else {
            
            if( validate_delivery ) {
              var address_line_1 = $$('input[name=address1]');
              if( address_line_1[0].getValue().empty() ) {
                if( address_fields_display == 'none' ) validates = th.show_message(item,validates,close_only);
              } else {
                this.close_message(id);
              }
            }
            
          }
          
        }
        // delivery check
        else if( item.hasClassName('delivery') ) {
          if( validate_delivery ) validates = th.default_check(item,validates,close_only);
        }
        // default check
        else { 
          validates = th.default_check(item,validates,close_only);
        }
        
      } 
    
    }
    
    return validates;
    
  },
  
  show_error: function(item,mismatch,length) {
  
    var id = item.name.camelize();
    var error_name = item.name + ( mismatch ? '_mismatch' : '' );
    if( length ) error_name = item.name + ( length ? '_length' : '' );
    
    if( $('error_'+id) ) {
    
      var error_id = 'error_'+id;
      //this.position_sort(item,$(error_id));
      
      $(error_id).update(errorMessage[error_name]);
      $(error_id).removeClassName('success');
      new Effect.Appear(error_id);
      
    } else {
      
      var span = new Element('span',{ 'id': 'error_'+id }).update(errorMessage[error_name]);
      span.addClassName('error');

      // sort positioning properly
      var offset = this.position_sort(item,span);
      
      item.insert({ 'after': span });
      span.absolutize();    
      var newLeft = span.getStyle('left');
      newLeft.replace('px','');
      newLeft = parseInt(newLeft) + offset;
      
      span.setStyle({ 'height': 'auto', 'width': 'auto', 'left': newLeft+'px' });
      
    }
    
    if( this.first_element ) item.focus();
    
  },
  
  default_check: function(item,validates,close_only) {
    
    var id = item.name.camelize();
    
    if( item.getValue().empty() ) {
      validates = this.show_message(item,validates,close_only);
    } else {
      this.close_message(id);
    }
    
    return validates;
    
  },
  
  close_message: function(id) {
    
    var error_box = $('error_'+id);
    if( error_box ) {
      error_box.update('Thanks!');
      error_box.addClassName('success');
      new Effect.Fade(error_box,{ 'delay': 0.3 });
    }
    
  },
  
  show_message: function(item,validates,close_only,mismatch,length) {
    
    if( !close_only ) {
      validates = false;
      this.show_error(item,mismatch,length);
      if( this.first_element ) this.first_element = false;
    }
    
    return validates;
    
  },
  
  position_sort: function(item,span) {
    
    offset = 0;
    
    var next_items = item.nextSiblings();
    next_items.each(function(sibling){
      if( sibling.tagName != 'A' && sibling.tagName != 'P' ) offset += sibling.getWidth();
    });
    
    return offset;
    
  }, 
  
  setFormValues: function(form) {

    var params = form.serialize(true);
    var url = '/shipping_values.html';

    new Ajax.Request(url,{
      method: 'post',
      parameters: params,
      onComplete: function(t) {
        var result = t.responseText;
      }
    });

  }
  
};

var tabSort = Class.create(); 
tabSort.prototype = {
  
  input_tabbed: false,
  input_tabbed_elm: undefined,
  list: undefined,
  
  initialize: function() {
    
    var th = this;
    var list = new Array();
    
    $$('form').each(function(form){
      
      if( form.hasClassName('validate') ) {
        
        form.getElements().each(function(elm){
          if( elm.type != 'hidden' ) {
            list.push(elm);
            elm.observe('keydown',th.tab_pressed.bindAsEventListener(th));
          }
        });
        
      }
      
    });
    
    th.list = list;
    
    new PeriodicalExecuter(function(pe){
      th.tab_check(th);
    }, 0.1);
    
  },
  
  tab_pressed: function(e) {
    
    var th = this;
    
    var key_pressed = ( e.keyCode == Event.KEY_TAB ) ? true : false;
    th.input_tabbed = key_pressed;
    th.input_tabbed_elm = $(Event.element(e));
    
  },
  
  tab_check: function(th) {
    
    if( th.input_tabbed ) {
      
      var focussed_elm = document.activeElement;
      
      if( focussed_elm.tagName == 'A' ) {
        get_next = false;
      
        th.list.each(function(elm){
          if( get_next ) {
            if( elm.focus ) elm.focus();
            get_next = false;
          }
          if( elm.nextSiblings().first() == focussed_elm ) {
            get_next = true;
          }
        });
      
        th.input_tabbed = false;
        th.input_tabbed_elm = undefined;
      }
      
    }
    
  }
  
};

function initValidation(){ newValidation = new Validate(); newTabSort = new tabSort(); }
document.observe('dom:loaded',initValidation);
