jQuery.core = jQuery.extend(jQuery.core, {
  ajax:{

    init:function(){
      var elements = jQuery.core.ajax.elements();
      if(elements.length > 0){
        elements.each(jQuery.core.ajax.bind);
      }
    },

    gateway:function(o){
      var o = o || false;
      if(typeof o == 'object' && typeof o['connector'] == 'string' && typeof o['point'] == 'string'){
        jQuery.ajaxSetup({
          cache:false,
          complete:jQuery.core.ajax.gateway,
          error:jQuery.core.ajax.gateway,
          beforeSend:function(request){
            jQuery('#loading').addClass('enabled');
            request.setRequestHeader('Server-Request-Connector',o['connector']);
            request.setRequestHeader('Server-Request-Point', o['point']);
            request.setRequestHeader('Server-Request-Accept', (typeof o['accept'] == 'object')?jQuery.param(o['accept']):null);
            request.setRequestHeader('Server-Request-Additional', (typeof o['additional'] == 'object')?jQuery.param(o['additional']):null);
            request.setRequestHeader('Server-Request-URL', (typeof o['url'] == 'string')?o['url']:null);
            request.setRequestHeader('Server-Request-Referer', location.href);
          }
        });
      }
      else{
        jQuery('#loading').removeClass('enabled');
        jQuery.ajaxSetup({
          beforeSend:function(request){
            request.setRequestHeader('Server-Request-Connector',null);
            request.setRequestHeader('Server-Request-Point', null);
            request.setRequestHeader('Server-Request-Accept', null);
            request.setRequestHeader('Server-Request-Additional', null);
            request.setRequestHeader('Server-Request-URL', null);
            request.setRequestHeader('Server-Request-Referer', null);
          }
        });
      }
      return;
    },

    elements:function(o){
      var o = jQuery.merge({'xpath':false,'all':false},(typeof o == 'object')?o:{});
      var elements = (o.all)?'a.ajax[rel],form.ajax[rel]':'a.ajax[rel]:not(".ajax-ready"),form.ajax[rel]:not(".ajax-ready")';
      return (o.xpath)?jQuery(elements,jQuery(o.xpath)):jQuery(elements);
    },

    structure:function(o){
      var o = o || false;
      var settings = jQuery(o).attr('rel');
      if(!settings) return false;
      settings = jsonParse(settings);
      if(
        typeof settings != 'object' ||
        typeof settings['connector'] != 'string' ||
        typeof settings['point'] != 'string' ||
        jQuery.trim(settings['connector']).length == 0 ||
        jQuery.trim(settings['point']).length == 0
      ) return false;
      if(jQuery(o).is('form')) settings['url'] = jQuery(o).attr('action');
      if(jQuery(o).is('a')) settings['url'] = jQuery(o).attr('href');
      if(jQuery.trim(settings['url']).length == 0){
        settings['url'] = location.href.replace(location.hash,'');
      }
      var matches = settings['url'].match(/(\#[^\#]+)$/img);
      if(matches && matches[0]){
        settings['additional'] = (typeof settings['additional'] == 'object')?settings['additional']:{};
        settings['additional']['receiver'] = matches[0];
        delete matches;
        var matches = settings['additional']['receiver'].match(/(\.[^\.]+)$/img);
        settings['additional']['receiver'] = (matches && matches[0])?matches[0]:settings['additional']['receiver'];
      }
      return settings;
    },

    bind:function(){
      var element=this, settings = jQuery.core.ajax.structure(this);

      switch(true){
        case (jQuery(element).is('form')):
          jQuery(element).ajaxForm({
            url:settings['url'],
            target:(settings && typeof settings['additional'] == 'object' && typeof settings['additional']['receiver'] == 'string')?settings['additional']['receiver']:null,
            beforeSubmit:function(fields,form,options){
              settings = jQuery.core.ajax.structure(element);
              if(!settings) return false;
              if(
                typeof window[new String(settings['connector'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])]['before'] == 'function' &&
                !window[new String(settings['connector'])][new String(settings['point'])]['before']({
                  'fields':fields,
                  'options':options,
                  'settings':settings,
                  'element':element
                })
              ) return false;
              jQuery.core.ajax.gateway(settings);
            },
            success:function(response, status, obj){
              if(
                typeof window[new String(settings['connector'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])]['after'] == 'function'
              ){
                var result = window[new String(settings['connector'])][new String(settings['point'])]['after']({
                  'element':element,
                  'settings':settings,
                  'options':obj,
                  'response':response
                });
                if(
                  typeof result == 'object' &&
                  typeof result['response'] != 'undefined' &&
                  typeof settings['additional'] == 'object' &&
                  typeof settings['additional']['receiver'] != 'undefined'
                ) jQuery(settings['additional']['receiver']).html(result['response']);
              }
              if(
                typeof response == 'object' &&
                typeof response['response'] == 'object' &&
                jQuery(response['response']).length > 0
              ){
                var action = ['html','text','append','prepend','before','after'];
                jQuery.each(response['response'],function(){
                  if(typeof this['xpath'] == 'string' && jQuery(this['xpath']).length>0){
                    for(var key in action){
                      if(typeof this[action[key]] == 'string') jQuery(this['xpath'])[action[key]](this[action[key]]);
                    }
                  }
                });
              }
              jQuery.core.ajax.init();
            }
          });
        break;

        case (jQuery(element).is('a')):
          jQuery(element).click(function(){return false;});
          jQuery(element).click(function(){
            var element = this, settings = jQuery.core.ajax.structure(element);
            if(!settings) return true;
            if(
              typeof window[new String(settings['connector'])] == 'object' &&
              typeof window[new String(settings['connector'])][new String(settings['point'])] == 'object' &&
              typeof window[new String(settings['connector'])][new String(settings['point'])]['before'] == 'function' &&
              !window[new String(settings['connector'])][new String(settings['point'])]['before']({
                'fields':null,
                'options':null,
                'settings':settings,
                'element':element
              })
            ) return false;
            jQuery.core.ajax.gateway(settings);
            jQuery.get(settings['url'],function(response){
              if(
                typeof window[new String(settings['connector'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])] == 'object' &&
                typeof window[new String(settings['connector'])][new String(settings['point'])]['after'] == 'function'
              ){
                var result = window[new String(settings['connector'])][new String(settings['point'])]['after']({
                  'element':element,
                  'settings':settings,
                  'options':null,
                  'response':response
                });
                if(typeof result == 'object' && typeof result['response'] != 'undefined') response = result['response'];
              }
              if(typeof settings['additional'] == 'object' && typeof settings['additional']['receiver'] == 'string') jQuery(settings['additional']['receiver']).html(response);
              if(
                typeof response == 'object' &&
                typeof response['response'] == 'object' &&
                jQuery(response['response']).length > 0
              ){
                var action = ['html','text','append','prepend','before','after'];
                jQuery.each(response['response'],function(){
                  if(typeof this['xpath'] == 'string' && jQuery(this['xpath']).length>0){
                    for(var key in action){
                      if(typeof this[action[key]] == 'string') jQuery(this['xpath'])[action[key]](this[action[key]]);
                    }
                  }
                });
              }
              jQuery.core.ajax.init();
              return false;
            });
          });
        break;
      }

      jQuery(element).addClass('ajax-ready');
    }

  }
});

/*
$.core.ajax.gateway({
    'connector':'box_tsnua',
    'point':'right_poll',
    'additional':{
        'var1':'result1',
        'var2':{
            'var21':'result21',
            'var22':{
                'var221':'result221'
            }
        }
    }
});

$.ajax('/')

var box_tsnua = {
  right_poll:{
    before:function(o){
      console.log(o);
      return true;
    },
    after:function(o){
      console.log(o);
      return {
        'response':'<h1>test</h1>'+o.response
      };
    }
  }
};

*/