var Ajax = $.inherit({
  __constructor:function(data){
    this.data = data;
    if(!this.__self.loader){
      this.createLoader();
    }
  },

  makeRequest: function(){
    this.modifyData();
    return $.ajax(this.data);
  },

  modifyData: function(){
    ajaxObj = this;
    this.data['beforeSend'] = function(){
      ajaxObj.__self.reqestCount++;
      ajaxObj.showLoader();
    }
    this.data['complete'] = function(){
      ajaxObj.__self.reqestCount = ajaxObj.__self.reqestCount - 1;
      if(ajaxObj.__self.reqestCount == 0){
        ajaxObj.hideLoader();
      }
    }
  },

  createLoader: function(){
    var e = $('<div></div>');
    e.attr('class', 'ajax-loader');
   // e.text(Lang.acp.loader.loading);
    $('body').append(e);
    this.__self.loader = e;
    return true;
  },

  showLoader: function(){
    ajaxObj.__self.loader.show();
    return true;
  },

  hideLoader: function(){
    ajaxObj.__self.loader.hide();
    return true;
  }
},
{
  reqestCount: 0
}
);

function randomNumber (m,n){
  m = parseInt(m);
  n = parseInt(n);
  return Math.floor( Math.random() * (n - m + 1) ) + m;
}

var Url = $.inherit({
	consts: {
		re0: /(?:([\w]+):\/\/)?(?:([\w]+)(?::([\w]+))?@)?([^\/:#\?]+)?(?::(\d+))?(.*)?/,
		re1: /^((?:[^\/]*\/)+)?([^#?]*)(\?[^#]*)?(?:#(.+))?/,
		fields: new Array('proto', 'user', 'password','host','path','file','anchor')
	},
	__constructor: function(url, full) {
		if (url){
			this.parse(url, full);
		}	
	},
	parse: function(url, full) {
		var $, i, a = this.consts.fields;
		for (i = 0; i < 7; ++i) delete this[a[i]];
		this.params = {};
		if (!url) return true;
		url = String(url);
		if (full === void 0) full = url.charAt(0) !== '/';
		if (full) {
			if ($ = this.consts.re0.exec(url)) {
				for (i = 0; i < 4; ++i) if ($[i + 1]) this[a[i]] = $[i + 1];
				url = $[6];
			} else return false;
		}
		if (!url) return true;
		$ = this.consts.re1.exec(url);
		if (full && $[1].charAt(0) !== '/') return false;
		if ($[1]) this.path = $[1];
		if ($[2]) this.file = $[2];
		if ($[3]) this.parseParams($[3]);
		if ($[4]) this.anchor = $[4];
		
		this.parseHashParams(url);
		return true;
	},
	parseParams: function(params) {
		var p = params.lastIndexOf('?');
		if (p !== -1) params = params.substr(p + 1);
		this.params = {};
		var params = params.split('&');
		if(params.length){
			for (var i = 0, v = [], l = params.length; i < l; ++i){
				v = params[i].split('=', 2);
				this.params[decodeURIComponent(v[0])] = v[1] !== void 0 ? decodeURIComponent(v[1]) : '';
			}
		}
		return this.params;
	},

	format: function(host, params) {
		if (host === void 0) host = !!this.host;
		var r = [];
		if (host) {
			if (this.proto) r.push(this.proto, '://'); else r.push(window.location.protocol, '//');
			if (this.host) {
				if (this.user) {
					r.push(this.user);
					if (this.password) r.push(':', this.password);
					r.push('@');
				}
				r.push(this.getHost());
			} else r.push(window.location.host);
		}
		if (this.path) r.push(this.path);
		if (this.file) r.push(this.file);
		if (params !== false) r.push(this.formatParams(true));
		if (this.hash){
      r.push('#', this.buildHashStr());
    }
		return r.join('');
	},
	toString: function() { return this.format(); },
	getHost: function() {
		if (!this.host) return window.location.host;
		var r = this.host;
		if (this.port) r += ':' + this.port;
		return r;
	},
	getPath: function() {
		if (!this.path) return this.host ? '/' : window.location.pathname.replace(/[^\/]*$/, '');
		if (this.path.charAt(0) === '/') return this.path;
		return (window.location.pathname.replace(/[^\/]*$/, '')) + this.path;
	},
	setParam: function(name, value) {
		this.params[name] = value !== void 0 ? value : '';
		return this;
	},
	setParams: function(params){
		if(params instanceof Object){
			for(var k in params){
				if(params[k] !== void 0){
					this.params[k] = params[k];
				}
			}
		}
		return this;
	},
	addParams: function(params) {
		if (arguments.length < 2) set = true;
		this.params = new Wak.Hash(this.params).set(params, set).h;
		return this;
	},
	formatParams: function(qmark) {
		if (!this.params) return '';
		if (qmark === void 0) qmark = true;
		var r = [], i = 0;
		for(var k in this.params){
			r[i] = encodeURIComponent(k) + '=' + encodeURIComponent(this.params[k]);
			i++;
		}
		r = r.join('&');
		if (qmark && r) r = '?' + r;
		return r;
	},
	
	parseHashParams: function(url) {
    this.hashStr = this.getHashDataFromUrl(url);
    this.hash = {};
		if(!this.hashStr.length || typeof(this.hashStr) !== 'string'){
			return false; 
    }
		var hparts = this.hashStr.split(';');
		for(num in hparts){
			var part = hparts[num];
			part = part.split(':');
			if(!part[1] || empty(part[1])){
				continue;
			}
      this.hash[part[0]] = part[1];
		}
		return true;
	},

	setHash:function(varName, value){
    this.hash[varName] = value.toString();
    return true;
	},

	getHashDataFromUrl:function(url) {
		hash = url.substring(url.lastIndexOf("#") + 1);
		if(!this.strpos(url, '#') || !this.strpos(hash, ':')){
			return false;
		}
		return url.substring(url.lastIndexOf("#") + 1);
	},

	strpos: function(haystack, needle, offset) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Onno Marsman    
    // +   bugfixed by: Daniel Esteban
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // *     example 1: strpos('Kevin van Zonneveld', 'e', 5);
    // *     returns 1: 14

    var i = (haystack+'').indexOf(needle, (offset || 0));
    return i === -1 ? false : i;
	},

  updateHash: function(){
    var str = this.buildHashStr();
    document.location.hash = '#'+str;
    return true;
	},

  buildHashStr: function(){
    var str = '';
    if($.isEmptyObject(this.hash)){
      return str;
    }
    for(var v in this.hash){
      if(typeof(this.hash[v]) == 'string' || typeof(this.hash[v]) == 'number'){
        str = str + (v + ':' + this.hash[v] + ';');
      }
		}
    return str;
  },

	getHashParams:function() {
		return this.hash;
	}

});
