/**
 * Fetches a page with url and parameters, then calls the callback function with the response as a parameter.
 */
var AjaxPageGetter = {
  handle:function(o) {
    this.callbackFunction(o.responseText);
  },
  startRequest:function(url, params, callbackFunction, method, scope) {
    method = useDefault(method, 'GET');
    this.callbackFunction = callbackFunction;
    this.scope = scope ? scope : this;
    YAHOO.util.Connect.asyncRequest(method, url, {
      success:this.handle,
      failure:this.handle,
      scope: this.scope
    }, params);
  }
};

/**
 * Posts a page with url and parameters, then calls the callback function with the response as a parameter.
 */
var AjaxPagePoster = {
  startRequest:function(url, params, callbackFunction) {
    AjaxPageGetter.startRequest(url, params, callbackFunction, 'POST');
  }
};

var AjaxJsonObjectRequest = {
  handle:function(o) {
    var json = undefined;
    try {
      json = parseJsonObject(o.responseText);
      if (this.callbackFunction) {
        if (this.scope)      this.callbackFunction.apply(this.scope, [json]);
        else        this.callbackFunction(json);
      }
    } catch (e) {
      if (this.failedCallbackFunction) {
        if (this.scope) this.failedCallbackFunction.apply(this.scope);
        else this.failedCallbackFunction();
      }
    }
  },
  startRequest:function(url, params, callbackFunction, failedCallbackFunction, method, scope) {
    method = useDefault(method, 'POST');
    this.callbackFunction = callbackFunction;
    this.failedCallbackFunction = failedCallbackFunction;
    this.scope = scope ? scope : this;
    YAHOO.util.Connect.asyncRequest(method, url, {
      success:this.handle,
      failure:this.handle,
      scope: this.scope
    }, params);
  }
};

/**
 * Submits a form then runs the callback function with the complete response object as parameter.
 * Use response.responseText to get the body of the response.
 */
var AjaxFormSubmitter = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(form, callbackFunction, action) {
    if (!action) action = form.action;
    this.callbackFunction = callbackFunction;
    YAHOO.util.Connect.asyncRequest('POST', checkAction(action), {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, formParametersToStringFormat(form));
  }
};

var AjaxRegisterUserFromForm = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(form, callbackFunction) {
    var url = '/ajax.user.registeruser.do.action';
    this.callbackFunction = callbackFunction;
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, formParametersToStringFormat(form));
  }
};

var AjaxLoginUser = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(email, password, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = '/ajax.user.loginuser.do.action';
    var parameters = new RequestParameters();
    parameters.addParameter("email", email);
    parameters.addParameter("password", password);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, parameters.toString());
  }
};

var AjaxLogoutUser = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = '/ajax.user.logoutuser.do.action';
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, undefined);
  }
};

var AjaxForgotPassword = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(email, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.forgotpassword.do');
    var parameters = new RequestParameters();
    parameters.addParameter("email", email);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, parameters.toString());
  }
};

var AjaxChangePassword = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(password, newPassword, newPasswordRepeat, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.changepassword.do');
    var parameters = new RequestParameters();
    parameters.addParameter("password", password);
    parameters.addParameter("newPassword", newPassword);
    parameters.addParameter("newPasswordRepeat", newPasswordRepeat);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, parameters.toString());
  }
};

var AjaxChangePasswordForm = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(form, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.changepassword.do');
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, formParametersToStringFormat(form));
  }
};

var AjaxChangeEmailForm = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(form, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.changeemail.do');
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, formParametersToStringFormat(form));
  }
};

var AjaxCheckEmail = {
  handle:function(o) {
    this.validatedFunction.apply(this.callbackScope,
      [parseJsonObject(o.responseText), this.customObject]
      );
  },
  startRequest:function(email, callbackFunction, callbackScope, customObject) {
    this.callbackScope = callbackScope;
    this.validatedFunction = callbackFunction;
    this.customObject = customObject;
    var url = '/ajax.user.checkemail.do.action';
    var parameters = new RequestParameters();
    parameters.addParameter("email", email);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope:this
    }, parameters.toString());
  }
};

var AjaxVerifyEmail = {
  handle:function(o) {
    this.validatedFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(email, code, callbackFunction) {
    this.validatedFunction = callbackFunction;
    var url = '/ajax.user.verifyemail.do.action';
    var parameters = new RequestParameters();
    parameters.addParameter("email", email);
    parameters.addParameter("code", code);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope:this
    }, parameters.toString());
  }
};

var AjaxVerifyNewEmail = {
  handle:function(o) {
    this.validatedFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(email, newEmail, code, callbackFunction) {
    this.validatedFunction = callbackFunction;
    var url = '/ajax.user.verifynewemail.do.action';
    var parameters = new RequestParameters();
    parameters.addParameter("email", email);
    parameters.addParameter("newEmail", newEmail);
    parameters.addParameter("code", code);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope:this
    }, parameters.toString());
  }
};

var AjaxCheckIsPasswordCorrect = {
  handle:function(o) {
    this.validatedFunction.apply(this.callbackScope,
      [parseJsonObject(o.responseText), this.customObject]
      );
  },
  startRequest:function(password, callbackFunction, callbackScope, customObject) {
    this.callbackScope = callbackScope;
    this.validatedFunction = callbackFunction;
    this.customObject = customObject;
    var url = '/ajax.user.ispasswordcorrect.do.action';
    var parameters = new RequestParameters();
    parameters.addParameter("password", password);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope:this
    }, parameters.toString());
  }
};


/** AJAX classes for traveller data requests **/

/**
 * Stores a traveller, returns SUCCESS and the resulting ID if success, otherwise FAILED.
 */
var AjaxStoreTraveller = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(form, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.storetraveller.do');
    var params = formParametersToStringFormat(form);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, params);
  }
};

/**
 * Deletes a traveller.
 */
var AjaxDeleteTraveller = {
  handle:function(o) {
    this.callbackFunction(parseJsonObject(o.responseText));
  },
  startRequest:function(id, callbackFunction) {
    this.callbackFunction = callbackFunction;
    var url = checkAction('ajax.user.deletetraveller.do');
    var parameters = new RequestParameters();
    parameters.addParameter("id", id);
    YAHOO.util.Connect.asyncRequest('POST', url, {
      success:this.handle,
      failure:this.handle,
      scope: this
    }, parameters.toString());
  }
};

/** General function that the AJAX classes depend upon **/

function evaluateAllChildrenScripts(element) {
  var scripts = element.getElementsByTagName('script');
  for (var i = 0; i < scripts.length; i++) {
    var script = scripts[i];
    //ibelog('evaluating: ' + script.innerHTML);
    eval(script.innerHTML);
  }
  // Run onLoad function.
  if (typeof onSubContentLoad == 'function') {
    onSubContentLoad();
  }
}

/**
 * Takes all fields of a form and assembles them into a GET formatted string with all variable names and values.
 * Example: id=35&name=mattias&age=12
 * @param form The form to use.
 */
function formParametersToStringFormat(form) {
  if (!form) {
    ibeerror('Form element is null.');
    return null;
  }
  var parameters = new RequestParameters(form);
  return parameters.toString();
}

function RequestParameters(form) {
  this.parameters = new Array();

  this.addParameter = function (parameterName, parameterValue) {
    this.parameters.push({"name":parameterName, "value":parameterValue});
  };

  if (form) {
    var es = form.elements;
    if (nullOrUndefined(es)) {
      ibeerror('No elements attribute in formElement with id=' + form.id);
      return;
    }
    for (var i = 0; i < es.length; i++) {
      var inputElement = es[i];
      if (inputElement.type != "radio") {
        this.addParameter(inputElement.name, inputElement.value);
      } else if (inputElement.checked) {
        this.addParameter(inputElement.name, inputElement.value);
      }
    }
  }

}

RequestParameters.prototype.toString = function() {
  var output = new Array();
  for (var i = 0; i < this.parameters.length; i++) {
    var p = this.parameters[i];
    var val = p.value;
    if (typeof val === "string" ||
        typeof val === "double" ||
        typeof val === "float") val = encodeURIComponent(val);
    output.push(p.name + "=" + val);
  }
  return output.join("&");
};

