var WaitFunction;
var GlobalResponceFunction;
var SendedAjaxIds = {};

var ERROR = 1;
var INFO = 2;
var WARNING = 3;
var DEBUG = 4;

function parse_url (str, component) {
    var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'],
        ini = (this.php_js && this.php_js.ini) || {},
        mode = (ini['phpjs.parse_url.mode'] && ini['phpjs.parse_url.mode'].local_value) || 'php',
        parser = {
            php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
            strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
            loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
        };
 
    var m = parser[mode].exec(str),
        uri = {},
        i = 14;
    while (i--) {
        if (m[i]) {
          uri[key[i]] = m[i];  
        }
    }
 
    if (component) {
        return uri[component.replace('PHP_URL_', '').toLowerCase()];
    }
    if (mode !== 'php') {
        var name = (ini['phpjs.parse_url.queryKey'] && 
                ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
        parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
        uri[name] = {};
        uri[key[12]].replace(parser, function ($0, $1, $2) {
            if ($1) {uri[name][$1] = $2;}
        });
    }
    delete uri.source;
    return uri;
}

function dump(text, type) {
  if (_$.browser.mozilla && window.console) {
    if (type == INFO)
      console.info(text);
    else if (type == ERROR)
      console.error(text);
    else if (type == DEBUG)
      console.debug(text)
    else if (type == WARNING)
      console.warn(text);
  } else {
    if (type == ERROR) {
      alert(text);
    }
  }
}

function ajaxErrorAlert(event, request, settings, error){
  StopWait("");

  error_start = "ajax error: ("+event.status+") ";
  http_error = {
    0:   'error connect to server',
    400: 'bad request',
    401: 'unauthorized',
    403: 'page forbidden',
    404: 'page not found',
    444: 'no response',
    500: 'internal server error',
    502: 'bad gateway',
    503: 'service unavailable',
    504: 'gateway timeout'
  };

  if (http_error[event.status]) {
    dump(error_start+http_error[event.status], ERROR);
  } else if (event.status==200 && request == "parsererror") {
    dump(error_start+"error parse responce", ERROR);
    dump(event["responseText"], DEBUG);
  } else {
    dump("ajax unknown error: ("+event.status+") " + event.statusText, ERROR);
    dump(event, DEBUG);
    dump(request, DEBUG);
    dump(settings, DEBUG);
    dump(error, DEBUG);
  }
}

function AjaxResponce(data, func) {
  if (!data) {
    ajaxErrorAlert({status:444});
    return;
  }
  StopWait(data.at);
  if (data.at == "logout") {
    alert("You have been logged out, please click OK and log back in to continue");
    var l = document.location;
    document.location.href=l.protocol+"//"+l.host+l.pathname+"?"+(new Date()).getTime();

    return;
  }
  if (data.user_errors) {
    alert(data.user_errors[0]);
  }
  if (data.errors) {
    for (i in data.errors) {
      alert(data.errors[i]);
      dump(data.errors[i], ERROR);
    }
  }
  php_time = data.php_time;
  responce_time = (new Date()).getTime() - data.start_time;

  if (isNaN(SendedAjaxIds[data.at]))
    SendedAjaxIds[data.at] = 0;

  ErrorTurn = 0;
  if (SendedAjaxIds[data.at] != parseInt(data.qid)) {
    ErrorTurn = 1;
    dump("AjaxResponce: Warning - incorect responce turn. \n Already - "+SendedAjaxIds[data.at]+"\n Now - "+data.qid, WARNING);
  }

  if (typeof(func)=="function") {
    func(data, ErrorTurn);
  }

  if (typeof(GlobalResponceFunction)=="function") {
    GlobalResponceFunction(data, ErrorTurn);
  }
}

function GetRequestId(at) {
  if (isNaN(SendedAjaxIds[at]))
    SendedAjaxIds[at] = 0;

  id = ++SendedAjaxIds[at];

  return id;
}

function SubmitAjaxForm(ap, at, formId, func, param) {
  dump("Request: " + at, INFO);
  var data = Array();
  if (formId == undefined || formId == null) {
  } else if (typeof(formId) == "string") {
    data = _$(formId).formToArray();
  } else if (typeof(formId) == "object") {
    data = formId;
  }

  start_time = (new Date()).getTime();
  action_page = param&&param["host"]?param["host"]:BASE_URL_AJAX.replace(/\/*$/g,'')+"/";
  U1 = parse_url(document.location.href);
  U2 = parse_url(action_page);
  if (U1["host"].replace('www.','')==U2["host"].replace('www.','')) {
    _$.post(U1["scheme"]+"://"+U1["host"]+U2["path"]+"?ap="+ap+"&at="+at+"&qid="+GetRequestId(at)+"&start_time="+start_time+"&ajax=1", data,  function(data) {AjaxResponce(data, func);}, "json");
  } else {
    data['ap']=ap;
    data['at']=at;
    data['qid']=GetRequestId(at);
    data['start_time']=start_time;
    data['ajax']=1;
    _$.get(action_page.replace(/\/*$/g,'')+"/?jsoncallback=?", data,  function(data) {AjaxResponce(data, func);}, "json");
  }
  
  Wait(at);
}

function Wait(at) {
  if (typeof(WaitFunction)=='function') {
    WaitFunction(at, 1);
  }
}

function StopWait(at) {
  if (typeof(WaitFunction)=='function') {
    WaitFunction(at, 0);
  }
}

WaitLoad('typeof(_$)=="function"', function(aa) {
  _$.ajaxSetup({
    global: false,
    error: ajaxErrorAlert,
    ajaxError: ajaxErrorAlert
  });
});
