/*
Script: Ajax.js
        Contains the <Ajax> class with extensions.
License:
        MIT-style license.
*/

var Ajax = new Class(
{
   Extends: Request,

   options:
   {
      isShowLoader: true,
      onShowLoader: null,
      onHideLoader: null,
      onHistory: null
   },

   initialize: function(options)
   {
      this.setOptions(options);
      this.parent();
      this.options.url = window.location.href;
      this.options.cdurl = this.options.url;
      this.options.evalResponse = true;
      this.options.evalScripts = true;
      this.currentHash = null;
      this.historyInterval = null;
      this.addEvent('onComplete', this.hideLoader);
   },

   call: function(func)
   {
      var params = "", i = 1, args = arguments;
      if (arguments.length == 2 && typeof(arguments[1]) == 'object')
      {
         args = arguments[1];
         i = 0;
      }
      params += "ajaxfunc=" + encodeURIComponent(func);
      for (; i<args.length; i++) params += "&ajaxargs[]=" + encodeURIComponent(this.encodeObj(args[i]));
      this.showLoader();
      return this.send(params);
   },

   cdcall: function(func)
   {
     var params = '', i = 1, args = arguments;
      if (arguments.length == 2 && typeof(arguments[1]) == 'object')
      {
         args = arguments[1];
         i = 0;
      }

      if (this.options.cdurl.charAt(this.options.cdurl.length - 1) != '?') params = '?';
      params += "ajaxfunc=" + encodeURIComponent(func);
      var url = this.options.cdurl.split('#');
      for (; i < args.length; i++) params += "&ajaxargs[]=" + encodeURIComponent(this.encodeObj(args[i]));
      document.getElementsByTagName('HEAD')[0].appendChild(new Element('script', {'src': url[0] + params, 'type': 'text/javascript'}));

   },

   encodeObj: function(param)
   {
      if (typeof(param) == 'object')
      {
         var obj = "<ajaxarray>";
         for (i in param)
         {
             if (i == 'constructor' || param[i] && ($type(param[i]) == 'function' || $type(param[i]) == 'object')) continue;
             obj += "<k>" + i + "</k><v>" + this.encodeObj(param[i]) + "</v>";
         }
         obj += "</ajaxarray>";
         return obj;
      }
      return param;
   },

   submit: function(func, form, target, url)
   {
      form = $(form);
      var old_target = form.target;
      var old_action = form.action;
      var old_method = form.method;
      var old_enctype = form.encoding;
      if (!url) url = this.options.url;
      form.action = url.replace('#', '') + (url.contains('?') ? '&' : '?') + "ajaxfunc=" + encodeURIComponent(func) + "&ajaxsubmit=1";
      form.method = 'post';
      form.target = target;
      form.encoding = 'multipart/form-data';
      form.submit();
      form.target = old_target;
      form.action = old_action;
      form.method = old_method;
      form.encoding = old_enctype;
   },

   showLoader: function()
   {
      if (this.options.isShowLoader)
      {
         if (document.body) document.body.style.cursor = 'wait';
         if (typeof(this.options.onShowLoader) == 'function') this.options.onShowLoader();
      }
   },

   hideLoader: function()
   {
      if (this.options.isShowLoader)
      {
         if (document.body) document.body.style.cursor = 'default';
         if (typeof(this.options.onHideLoader) == 'function') this.options.onHideLoader();
      }
   },

   startHistory: function()
   {
      this.currentHash = window.location.hash;
      if (window.ie)
      {
       var el = new Element('iframe', {'styles': {'display': 'none'}, 'id': 'ajax_historyFrame'});
         el.inject(document.body, 'top');
         var iframe = $('ajax_historyFrame').contentWindow.document;
         iframe.open();
         iframe.close();
         iframe.location.hash = this.currentHash;
         if (!this.currentHash) this.currentHash = '#';
      }
     this.historyInterval = setInterval(this.history, 100);
   },

   addHistory: function(hash)
   {
     if (window.ie)
     {
        var iframe = $('ajax_historyFrame').contentWindow.document;
         iframe.open();
         iframe.close();
         iframe.location.hash = hash;
     }
     window.location.hash = hash;
   },

   stopHistory: function()
   {
     clearInterval(this.historyInterval);
     this.currentHash = null;
     this.historyInterval = null;
   },

   history: function()
   {
      var hash;
      if (window.ie) hash = $('ajax_historyFrame').contentWindow.document.location.hash;
      else hash = window.location.hash;
      if (this.currentHash != hash)
      {
         this.currentHash = hash;
         if (window.ie) window.location.hash = hash;
         if (typeof(this.onHistory) == 'function') this.onHistory(this.currentHash.substr(1));
      }
   },

   submitProgress: function(func, form, target, callback)
   {
      this.isShowLoader = false;
      this.submit(func, form, target);
      var id = target.substr(6);
      setTimeout("ajax.call('" + callback + "', $('ajax_progress_key_" + id + "').value, '" + id + "')", 2000);
   },

   cleanProgress: function()
   {
      $('ajax_progress_window_filename').set('html', '')
      $('ajax_progress_window_total').set('html', '0')
      $('ajax_progress_window_current').set('html', '0')
      $('ajax_progress_window_rate').set('html', '')
      $('ajax_progress_window_progressbar').set('html', '')
      this.isShowLoader = true;
   }

});