	var callback_urls_waiting = 0;
	var callback_urls;
	var callback_type;
	
function check_message(element) {

	if (element.id=="message_recipient_msisdn") {
		if (element.value.length > 0) {
			var ok = check_msisdn(element.value,network_prefixes_sms);
			if (ok==0) {
				element.className = "error";
				return;
			} else if (ok==1) {
				element.className = "ok";
			} else {
				element.className = "";
			}
		} else {
			element.className = "";
			return;
		}
	}

	if (element.id=="message_text") {
		sms_message_char_counter();

		if (element.value.length > 0) {
				element.className = "ok";
		} else {
			element.className = "";
			return;
		}
	}

	var message_recipient_msisdn = dom.byId("message_recipient_msisdn");
	var message_text = dom.byId("message_text");

	if (message_recipient_msisdn.className=="ok" && message_text.className=="ok") {
		step_enable_next('message');
	}
}

function check_send_validation(element) {
	
	if (element.id=="mobile_operator_id") {
		if (element.value.length > 0) {
				element.className = "ok";
		} else {
			element.className = "";
			return;
		}
	}

	if (element.id=="msisdn") {
		if (element.value.length > 0) {
			var ok = check_msisdn(element.value,network_prefixes);
			if (ok==0) {
				element.className = "error";
				return;
			} else if (ok==1) {
				element.className = "ok";
			} else {
				element.className = "";
			}
		} else {
			element.className = "";
			return;
		}
	}
}

function process_send_validation() {

	var mobile_operator_id = dom.byId("mobile_operator_id");
	var msisdn = dom.byId("msisdn");
	var button = dom.byId("button_send_validation");

	if (mobile_operator_id.className=="ok" && msisdn.className=="ok" && button.style.cursor != "wait") {

		step_disable_all_next('send_validation');

		hide_error("error_send_validation");
		button.style.cursor = "wait";

		processed_send_validation();
	}
}

function processed_send_validation(request) {
	step_enable_next('send_validation');
	process_order_abo();
	dom.byId("button_send_validation").style.cursor = "pointer";
}

function error_send_validation() {
  show_error("error_send_validation");
  dom.byId("button_send_validation").style.cursor = "pointer";
}

function check_verify_validation(element) {

	if (element.id=="validation_code") {
		element.className = "";
		return;
	}
}

var abo_registration_id = 0;

function check_order_abo(element) {
	check_send_validation(element);
}

function process_order_abo() {

	var mobile_operator_id = dom.byId("mobile_operator_id");
	var msisdn = dom.byId("msisdn");
	var button = dom.byId("button_order_abo");

	var validation_code = dom.byId("validation_code");

	if ((!mobile_operator_id || mobile_operator_id.className=="ok") && msisdn.className=="ok" && (!validation_code || validation_code.className=="ok") && abo_registration_id==0) {

		hide_error("error_order_abo");
		if (button) button.style.cursor = "wait";

		var post = 'cmd=order_abo&msisdn='+msisdn.value;
		if (mobile_operator_id) post = post+'&mobile_operator_id='+mobile_operator_id.value;
		if (validation_code) post = post+'&code='+validation_code.value;
		new ajax('/sms/abo/xml.fcgi', {postBody: post, onComplete: processed_order_abo});
	}
}

function processed_order_abo(request) {
	var tr_xml = dom.treeXML(request.responseXML.documentElement);
	if (tr_xml.Ok[0].data == "1") {
		abo_registration_id = tr_xml.PlusRegistrationId[0].data;
		var step_check_abo = step_get('check_abo');
		if (step_check_abo >= 0) {
			step_enable(step_check_abo);
		} else {
			//show_waiting_screen();
		}
		window.setTimeout("process_check_abo()",5000);
	} else {
		show_error("error_order_abo", tr_xml.Error[0].data);

		if (tr_xml.ErrorElement) {
			eval('dom.byId(tr_xml.ErrorElement[0].data).className = "error"');
		}

		var button = dom.byId("button_order_abo");
		if (button) button.style.cursor = "pointer";
	}
}

function error_order_abo() {
  show_error("error_order_abo");
  var button = dom.byId("button_order_abo");
  if (button) button.style.cursor = "pointer";
}

function process_check_abo() {
	if (abo_registration_id > 0) {
		var post = 'cmd=check_abo&plus_registration_id='+abo_registration_id;
		new ajax('/sms/abo/xml.fcgi', {postBody: post, onComplete: processed_check_abo, onError: error_check_abo});
	}
}

function processed_check_abo(request) {
	var tr_xml = dom.treeXML(request.responseXML.documentElement);
	if (tr_xml.Ok[0].data == "1") {
		var step_check_abo = step_get('check_abo');
		if (step_check_abo == -1 || step_check_abo == (steps.length-1)) {
			if (tr_xml.CallbackUrl) {
			  if (tr_xml.CallbackType[0].data == "image") {
			    callback_urls_waiting = tr_xml.CallbackUrl.length;
          var preloader = new ImagePreloader(tr_xml.CallbackUrl, callback_urls_loaded, '');
			  }
			} else {
			  document.sms.submit();
			}
		} else {
		  if (tr_xml.CallbackUrl) {
			  if (tr_xml.CallbackType[0].data == "image") {
			    callback_urls_waiting = tr_xml.CallbackUrl.length;
          var preloader = new ImagePreloader(tr_xml.CallbackUrl, callback_urls_loaded_step_enable_next, '');
			  }
			} else {
			  step_enable_next('check_abo');
			}
		}
	} else if (tr_xml.Ok[0].data == "2") {
		window.setTimeout("process_check_abo()",5000);
	} else {
		show_error("error_order_abo", tr_xml.Error[0].data);

		abo_registration_id = 0;

		var step_check_abo = step_get('check_abo');
		if (step_check_abo >= 0) {
			step_disable_all_next('order_abo');
		} else {
		  hide_waiting_screen();
		}
		var button = dom.byId("button_order_abo");
		if (button) button.style.cursor = "pointer";
	}
}

function error_check_abo() {
	window.setTimeout("process_check_abo()",5000);
}

function show_waiting_screen() {
	var cover = dom.byId('waiting_screen_cover');
	var overlay = dom.byId('waiting_screen_overlay');

	overlay.style.height = cover.offsetHeight+'px';
	overlay.style.visibility = "visible";
}

function hide_waiting_screen(step) {
	dom.byId('waiting_screen_cover').style.visibility = "visible";
}

function step_disable(step) {
	var table = dom.byId('step_'+step);
	var div_disable = dom.byId('step_disable_'+step);

	div_disable.style.width = (table.offsetWidth+1)+'px';
	div_disable.style.height = table.offsetHeight+'px';
	div_disable.style.visibility = "visible";
}

function step_enable(step) {
	var div_disable = dom.byId('step_disable_'+step);
	div_disable.style.visibility = "hidden";
}

function step_disable_all_next(step_name) {
	var start = 99;
	for (var i=0;i<steps.length;i++) {
		if (step_name == steps[i]) start = i+1;
		if (i >= start) step_disable(i);
	}
}

function step_enable_next(step_name) {
	for (var i=0;i<steps.length;i++) {
		if (step_name == steps[i]) {
			step_enable(i+1);
			return;
		}
	}
}

function step_get(step_name) {
	for (var i=0;i<steps.length;i++) {
		if (step_name == steps[i]) {
			return i;
		}
	}
	return -1;
}


  function callback_urls_loaded(aImages, nImages, return_href) {
    if ( nImages != callback_urls_waiting ) {
      // Images didnt load properly
      if (dom.byId("image_load_info")) {
        dom.byId("image_load_info").innerHTML = '<b>Incomplete Image Load.</b>';
      }
    }
    document.sms.submit();
    // do nothing window.location.href = return_href;
  }
  function callback_urls_loaded_step_enable_next(aImages, nImages, return_href) {
    step_enable_next('check_abo');
  }  


function ImagePreloader(imagesrcs, callback, return_href) {

   // store the call-back
   this.callback = callback;
   
   // store my return link
   this.return_href = return_href;
   
   // initialize internal state.
   this.nLoaded = 0;
   this.nProcessed = 0;
   this.aImages = new Array;

   // record the number of images.
   this.nImages = imagesrcs.length;
 
   // for each image, call preload()
   for ( var i = 0; i < imagesrcs.length; i++ ) 
      this.preload(imagesrcs[i].data);
}

ImagePreloader.prototype.preload = function(image) {
   // create new Image object and add to array
   var oImage = new Image;
   this.aImages.push(oImage);
   
   // set up event handlers for the Image object
   oImage.onload = ImagePreloader.prototype.onload;
   oImage.onerror = ImagePreloader.prototype.onerror;
   oImage.onabort = ImagePreloader.prototype.onabort;
   
   // assign pointer back to this.
   oImage.oImagePreloader = this;
   oImage.bLoaded = false;
   
   // assign the .src property of the Image object
   oImage.src = image;
}

ImagePreloader.prototype.onComplete = function() {
   this.nProcessed++;
   if ( this.nProcessed == this.nImages ) {
      this.callback(this.aImages, this.nLoaded, this.return_href);
   }
}

ImagePreloader.prototype.onload = function() {
   this.bLoaded = true;
   this.oImagePreloader.nLoaded++;
   this.oImagePreloader.onComplete();
}

ImagePreloader.prototype.onerror = function() {
   this.bError = true;
   this.oImagePreloader.onComplete();
}

ImagePreloader.prototype.onabort = function() {
   this.bAbort = true;
   this.oImagePreloader.onComplete();
}

/* START SubmitFormOnEnter */
function SubmitFormOnEnter(elem,cancel,fn){
   
   var me = this;
   this.elem = document.getElementById(elem);
   
  //Keycodes que devem ser monitorados
   var ENTER = 13;
   
   //Rotina no KEYUP (pegar input)
   me.elem.onkeyup = function(ev) {
     var key = me.getKeyCode(ev);
	   
	   check_send_validation(this);
	   
     if (key == ENTER) {
      if (fn) {
        // dont submit, call function, cancel event bubbleing
        fn();
      } else {
        var frm = me.elem.form;
        frm.submit();
        me.cancelEvent(ev);
      }
      if (cancel == true) me.cancelEvent(ev);
     }
   };
   
   me.elem.onkeydown = function(ev) {
     var key = me.getKeyCode(ev);
     
     if (key == ENTER) {
       if (cancel == true) me.cancelEvent(ev);
     }
   };
   
   
  //HELPER FUNCTIONS
   
   /********************************************************
   Helper function to determine the keycode pressed in a 
   browser-independent manner.
   ********************************************************/
   this.getKeyCode = function(ev)
   {
    if(ev)   //Moz
    {
     return ev.keyCode;
    }
    if(window.event) //IE
    {
     return window.event.keyCode;
    }
   };
   
   /********************************************************
   Helper function to determine the event source element in a 
   browser-independent manner.
   ********************************************************/
   this.getEventSource = function(ev)
   {
    if(ev)   //Moz
    {
     return ev.target;
    }
   
    if(window.event) //IE
    {
     return window.event.srcElement;
    }
   };
   
   /********************************************************
   Helper function to cancel an event in a 
   browser-independent manner.
   (Returning false helps too).
   ********************************************************/
   this.cancelEvent = function(ev)
   {
    if(ev)   //Moz
    {
     ev.preventDefault();
     ev.stopPropagation();
    }
    if(window.event) //IE
    {
     window.event.returnValue = false;
    }
   }
  }
  /* END SubmitFormOnEnter */