/*  Arta-engine js object - requires JQuery and JQueryUI
    Copyright (C) 2009 - 2011 by Mehdi Torabi, Arta engine (http://artaengine.com/)
 
    Dual licensed under the: MIT or GNU General Public License (GPL) version 3 licenses.
    http://artaengine.com/license

    version: 1.0.1
    Created: 2010-10-20 - Mehdi Torabi
    Updated: 2011-12-15 - Mehdi Torabi */

var Arta = {
  errors: null,      // form validate errors
  listOptions: null, // table options
  sortOptions: null, // table col sort options
  lastAccessTime: new Date(), // last time something happened
  temp: null,
  busy: 0, // count of busy ajax calls
  dialog: 'msg-box',
  /* escape JQuery selectors */
  escJQ: function(str)
  {
    return str.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/@])/g,'\\$1');
  },
  /* Messagebox - using JQuery UI messagebox */
  msg: function(title, content, w, h, buttons, settings)
  {
    var id = Arta.dialog,
        e = $('#'+Arta.dialog);
    if(e.length == 0)
    {
      alert(title+'\n\n'+content);
      return;
    }
    buttons = typeof(buttons)=='undefined'? {}: buttons;
    if(typeof(e.dialog) == 'undefined')
    {
      var buttonHTML = '', i = 0;
      $.each(buttons, function(k, v) {
          Arta['f'+(++i)] = v==='close'? function() { $('#'+id).hide(); }: v;
          buttonHTML += '<input type="button" value="'+k+'" onclick="Arta.f'+i+'();" />';
      });
      e.html('<h2 id="'+id+'-title">'+title+'</h2><div id="'+id+'-content">'+
          content+'<div id="'+id+'-buttons">'+buttonHTML+'</div></div>').show('fast');
      return;
    }
    $.each(buttons, function(k, v) {
        if(v === 'close')
          buttons[k] = function() { $(this).dialog('close'); };
    });
    var w = typeof(w)=='undefined'? 400: w,
        h = typeof(h)=='undefined'? 200: h;
    options = {
      title: title,
      dialogClass: Arta.dialog,
      resizable: false,
      modal: true,
      buttons: buttons
    };
    if(typeof(settings) != 'undefined')
      options = jQuery.extend(options, settings);
    if(typeof(w) == 'string') options.minWidth  = w; else options.width  = w;
    if(typeof(h) == 'string') options.minHeight = h; else options.height = h;
    e.html(content).dialog(options);
  },
  msgClose: function()
  {
    var e = $('#'+Arta.dialog);
    typeof(e.dialog)=='undefined'? e.hide(): e.dialog('close');
  },
  /* Delete confirmation dialog */
  deleteConfirm: function(id, url, modelGroup, model, fn)
  {
    var treeStyle = typeof(modelGroup)!='undefined' && typeof(model)!='undefined',
        clsL = typeof(tS)=='object'? tS.clsL: Dashboard.settings.clsL,
        msgContent = '<h3>'+i18n.deleteMsg+':</h3>';
    if(treeStyle)
      msgContent += '<div id="delete-tree-dependencies"></div>';
    else
    {
      msgContent += '<ul>';
      $('#'+clsL+id+' > td').each(function(index) {
        var text = $(this).html();
        var th = $('#'+clsL+'-trhead > th:eq('+index+')');
        if(th.length > 0 && th.text().length > 0)
          msgContent += '<li class="clearfix"><label>'+th.text()+': </label><b>'+text+'</b></li>';
      });
      msgContent += '</ul>';
    }
    var buttons = {};
    buttons[i18n.cancel] =
        treeStyle?
            function() {
                Arta.ajax('DeleteTree/delete/close/'+Arta.temp+'/', {}, 'get', function(oJ) { });
                Arta.msgClose(); 
            }:
            'close';
    buttons[i18n.del] = treeStyle?
        function() {
            Arta.ajax('DeleteTree/delete/use/'+Arta.temp+'/', {}, 'get', function(oJ) {
                if(typeof(fn) == 'function')
                  fn();
                else
                {
                  $('#link-list').trigger('click');
                  $('.spec-tab, #record-identifier').hide();
                  if(typeof(refreshList) == 'function')
                    refreshList();
                  else
                    Dashboard.list();
                }
            });
            Arta.msgClose();
        }:
        function() {
          Arta.ajax(url, {}, 'post', function(oJ) {
              if(typeof(fn) == 'function')
                fn();
              else
              {
                $('#link-list').trigger('click');
                $('.spec-tab, #record-identifier').hide();
                if(typeof(refreshList) == 'function')
                  refreshList();
                else
                  Dashboard.list();
              }
          });
          Arta.msgClose();
        };
    Arta.msg(i18n.deleteTitle, msgContent, 700, 600, buttons);
    if(treeStyle)
    {
      var b = $('.ui-dialog-buttonpane, #'+Arta.dialog+'-buttons');
      b.hide();
      Arta.ajax('DeleteTree/render/'+modelGroup+'/'+model+'/'+id, {}, 'get', function(oJ) {
          Arta.temp = oJ.key;
          b.show();
      });
    }
    return false;
  },
  /* Adjust sort arrow on table col */
  sortDirection: function(oJ, cls)
  {
    if(typeof(oJ) == 'object' && Arta.sortOptions === null && typeof(oJ.sort) == 'string')
    {// for multi class
      if(typeof(oJ.sort) == 'undefined')
        return;
      var s = oJ.sort.split(' ');
      Arta.sortOptions = {col: cls+'___'+s[0], order: s[1]};
    }
    $('#sort-'+Arta.escJQ(Arta.sortOptions.col)).addClass(Arta.sortOptions.order);
  },
  /* On table col sort click */
  sortX: function(e, col, fn)
  {
    var key = $(e).attr('id').split('-').pop();
    if(typeof(col) == 'undefined' || !col)
      col = key.split('___').pop();
    Arta.sortOptions.col = key;
    Arta.sortOptions.order = $('#sort-'+Arta.escJQ(key)).hasClass('asc')? 'desc': 'asc';
    Arta.listOptions.sort = col+' '+Arta.sortOptions.order;
    Arta.listOptions.page = 1;
    if(typeof(fn) == 'function')
      fn();
    else if(typeof(refreshList) == 'function')
      refreshList();
    else
      Dashboard.list();
  },
  /* Paging link */
  pageList: function(page, fn)
  {
    Arta.listOptions.page = page;
    if(typeof(fn) == 'function')
      fn();
    else if(typeof(refreshList) == 'function')
      refreshList();
    else
      Dashboard.list();
  },
  /* Validation regExps */
  reg: function(i, val)
  {
    ex = {
      ui: /^\d+$/,
      si: /^[+-]?\d+$/,
      uf: /^((\d+(\.\d *)?)|((\d*\.)?\d+))$/,
      sf: /^[+-]?((\d+(\.\d *)?)|((\d*\.)?\d+))$/,
      e:  /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i,
      u:  /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i,
      t:  /^([0-9]|[0-1][0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/,
      d:  /^[0-3][0-9][0-9][0-9][\/-]([0-9]|0[0-9]|1[0-2])[\/-]([0-9]|[0-2][0-9]|3[01])$/,
      dt: /^[0-3][0-9][0-9][0-9][\/-]([0-9]|0[0-9]|1[0-2])[\/-]([0-9]|[0-2][0-9]|3[01])\s([0-9]|[0-1][0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/,
      i:  /^(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)\.(1\d{0,2}|2(?:[0-4]\d{0,1}|[6789]|5[0-5]?)?|[3-9]\d?|0)(\/(?:[012]\d?|3[012]?|[456789])){0,1}$/
    };
    return ex[i].test(val);
  }, 
  /* Form valiation msg */
  validateMsg: function(popup)
  {
    var msgs = [], t, k;
    $.each(Arta.errors, function(id, type) {
        label = $('#'+Arta.escJQ(id)+'-label').text();
        if(!label)
          label = $('#'+id.replace('-text', '')+'-label').text();
        if(!label)
          label = id;
        t = typeof(i18nValidate) == 'undefined' || typeof(i18nValidate[id]) == 'undefined'
          || typeof(i18nValidate[id][type]) == 'undefined'? i18n[type]: i18nValidate[id][type];
        msgs.push('<li class="clearfix"><label>'+label+'</label><span>'+t+'</span></li>');
    });
    var msg = '<ul id="validate-msg">'+msgs.join('')+'</ul>';
    if(typeof(popup) != 'undefined' && !popup)
        return msg;
    Arta.msg(i18n.frmVTitle, msg, 400, 400);
    return false;
  },
  /* form:  jquery selector */
  validate: function(form)
  {
    form = typeof(form)=='undefined'? '': form+' ';
    $(form+'.input-bad').removeClass('input-bad');
    Arta.errors   = {};
    var err       = false,
        vals      = {},
        nulls     = [],
        formFound = false;
    /* extract validation data from class */
    var extractClass = function(e) {
      var classes = $(e).attr('class'),
          out = {minV: '', maxV: '', minL: '', reg: ''};
      if(typeof(classes) != 'undefined')
        $.each(classes.split(' '), function(i, cls) {
            if(cls.indexOf('min') > -1) out.minV = parseInt(cls.replace('min', ''), 10);
            if(cls.indexOf('max') > -1) out.maxV = parseInt(cls.replace('max', ''), 10);
            if(cls.indexOf('minlength') > -1) out.minL = parseInt(cls.replace('minlength', ''), 10);
            if(cls.indexOf('regex') > -1) out.reg = cls.replace('regex', '');
        });
      return out;
    };
    /* error */
    var error = function(e, id, type) {
      if(e)
        e.addClass('input-bad');
      if(id)
        Arta.errors[id] = type;
      return true;
    };
    /* check input/select/text vals */
    $(form+"input[type!='radio'][type!='checkbox'], "+form+'select, '+form+'textarea')
    .not('.ignore').each(function() {
        var e     = $(this),
            v     = e.val(),
            id    = e.attr('id'),
            ext   = extractClass(this),
            isObj = false,
            cp    = e.hasClass('password-confirm');
        if(typeof(id) == 'undefined')
          id = '';
        if(!formFound && e.parents('form').length > 0)
        {
          formFound = true;
          formE = e.parents('form');
        }
        /* val */
        if(e.hasClass('CKEDITOR'))
          v = CKEDITOR.instances[id].getData();
        if(typeof(v) == 'object')
        {
          isObj = true;
          if(!v || !v.length)
            v = e.hasClass('widget-empty')? '': {};
        }
        else
          v = jQuery.trim(v);
        /* REQUIRED */
        var filled = v!=='';
        if(e.hasClass('required') && !cp && ((!isObj && !filled) || (isObj && (!v || !v.length))))
        {
          if(id.substr(-5) == '_date')
            id2 = id.substr(0, id.length-5);
          else if(id.substr(-2) == '_M')
            id2 = id.substr(0, id.length-2);
          else if(id.substr(-2) == '_H')
            id2 = id.substr(0, id.length-2);
          else if(id.substr(-2) == '_S')
            id2 = id.substr(0, id.length-2);
          else if(id.substr(-7) == '-number')
            id2 = id.substr(0, id.length-7);
          else if(id.substr(-13) == '-country-code')
            id2 = id.substr(0, id.length-13);
          else if(id.substr(-10) == '-city-code')
            id2 = id.substr(0, id.length-10);
          else
            id2 = id;          
          err = error(e, id2, 'frmVRequired');
        }
        /* REGEX */
        if(ext.reg)
        {
          var reg = new RegExp(ext.reg);
          if(!reg.test(v))
            return err = error(e, id, 'frmVReg');
        }
        /* MIN LEN */
        if(ext.minL && ext.minL > v.length && v.length > 0)
          return err = error(e, id, 'frmVLenMin');
        /* MAX LEN */
        var maxlen = e.attr('maxlength');
        if(typeof(maxlen) != 'undefined')
        {
          maxlen = parseInt(maxlen);
          if(maxlen != -1 && maxlen != 524288 && maxlen != 2147483647 && v.length > maxlen)
            return err = error(e, id, 'frmVLenMax');
        }
        /* PHONE */
        if(e.hasClass('hidden-phone')) {
          var id1 = id+'-number', number = jQuery.trim($('#'+id1).val()),
              id2 = id+'-country-code', countryCode = jQuery.trim($('#'+id2).val()),
              id3 = id+'-city-code', cityCode = jQuery.trim($('#'+id3).val()),
              pErr = false;
          if(typeof(Arta.errors[id1]) != 'undefined') {
            delete Arta.errors[id1];
            pErr = true;
          }
          if(typeof(Arta.errors[id2]) != 'undefined') {
            delete Arta.errors[id2];
            pErr = true;
          }
          if(typeof(Arta.errors[id3]) != 'undefined') {
            delete Arta.errors[id3];
            pErr = true;
          }
          var allEntered = number!='' && countryCode!='' && cityCode!='';
          if(pErr || (allEntered && (
              !Arta.reg('ui', number) ||
              !Arta.reg('ui', countryCode) ||
              !Arta.reg('ui', cityCode))))
          {
            $('#'+id1+', #'+id2+', #'+id3).addClass('input-bad');
            return err = error(e, id, 'frmVPhone');
          }
          v = allEntered? '+'+countryCode+'-'+cityCode+'-'+number: '';
          e.val(v);
        }
        /* INT */
        else if(e.hasClass('int')) {
          if(filled) {
            if(!(e.hasClass('unsigned')? Arta.reg('ui', v): Arta.reg('si', v)))
              return err = error(e, id, 'frmVInt');
            v = parseInt(v, 10);
          }
        }
        /* FLOAT */
        else if(e.hasClass('float')) {
          if(filled) {
            v = v.replace(',', '.').replace('/', '.');
            if(!(e.hasClass('unsigned')? Arta.reg('uf', v): Arta.reg('sf', v)))
              return err = error(e, id, 'frmVFloat');
            v = parseFloat(v);
          }
        }
        /* PASSWORD MATCH */
        else if(e.hasClass('password')) {
          var pc = $('#'+id+'-confirm');
          if(v != jQuery.trim(pc.val()))
          {
            e.val('');
            pc.val('');
            pc.addClass('input-bad');
            return err = error(e, id, 'frmVPassword');
          }
          v = vals[id+'-confirm'] = typeof($.sha1)=='function'? $.sha1(v): v;
        }
        /* EMAIL */
        else if(e.hasClass('email')) {
          if(filled && !Arta.reg('e', v))
            return err = error(e, id, 'frmVEmail');
        }
        /* URL */
        else if(e.hasClass('url')) {
          if(filled && !Arta.reg('u', v))
            return err = error(e, id, 'frmVURL');
        }
        /* IP */
        else if(e.hasClass('IP')) {
          if(filled && !Arta.reg('i', v))
            return err = error(e, id, 'frmVIP');
        }
        /* DATE */
        else if(e.hasClass('date')) {
          if(filled && !Arta.reg('d', v))
            return err = error(e, id, 'frmVDate');
        }
        /* TIME */
        else if(e.hasClass('timepick')) {
          var tH = $('#'+id+'_H').length? jQuery.trim($('#'+id+'_H').val()): '00',
              tM = $('#'+id+'_M').length? jQuery.trim($('#'+id+'_M').val()): '00',
              tS = $('#'+id+'_S').length? jQuery.trim($('#'+id+'_S').val()): '00';
          v = (filled=(tH!==''))? (tH+':'+(tM===''? '00': tM)+':'+(tS===''? '00': tS)): '';
          if(filled && !Arta.reg('t', v))
          {
            $('#'+id+'_H, #'+id+'_M, #'+id+'_S').addClass('input-bad');
            return err = error(e, id, 'frmVTime');
          }
          e.val(v);
        }
        /* DATETIME */
        else if(e.hasClass('datetime')) {
          var dT = jQuery.trim($('#'+id+'_date').val()),
              tH = $('#'+id+'_H').length? jQuery.trim($('#'+id+'_H').val()): '00',
              tM = $('#'+id+'_M').length? jQuery.trim($('#'+id+'_M').val()): '00',
              tS = $('#'+id+'_S').length? jQuery.trim($('#'+id+'_S').val()): '00';
          v = (filled=(dT!==''))? (dT+' '+(tH===''? '00': tH)+':'+(tM===''? '00': tM)+':'+(tS===''? '00': tS)): '';
          if(filled && !Arta.reg('dt', v))
          {
            $('#'+id+'_date, #'+id+'_H, #'+id+'_M, #'+id+'_S').addClass('input-bad');
            return err = error(e, id, 'frmVDatetime');
          }
          e.val(v);
        }
        /* MIN MAX */
        if(filled && !cp)
        {
          if(ext.minV && ext.minV > v)
            return err = error(e, id, 'frmVMin');
          if(ext.maxV && ext.maxV < v)
            return err = error(e, id, 'frmVMax');
        }
        /* * */
        if(!id)
          return;
        if(!isObj && !filled)
          nulls.push(id);
        vals[id] = v;
    });
    /* RADIO */
    var radios = $(form+"input[type='radio']").not('.ignore');
    radios.each(function() {
        var e  = $(this),
            id = e.attr('name');
        if(!formFound && e.parents('form').length > 0)
        {
          formFound = true;
          formE = e.parents('form');
        }
        if(e.is(':checked') && typeof(id) != 'undefined')
          vals[id] = jQuery.trim(e.val());
    }).each(function() {
        var e  = $(this),
            id = e.attr('name');
        if(e.hasClass('required') && typeof(id) != 'undefined' &&
            (typeof(vals[id]) == 'undefined' || vals[id] == ''))
          err = error(e, id, 'frmVRequired');
    });
    /* CHECKBOX */
    var checks = {}, requiredA = {}, indexId = /^.*\[\d*\]$/;
    $(form+"input[type='checkbox']").not('.ignore').each(function() {
        var e  = $(this),
            id = e.attr('id'),
            v  = jQuery.trim(e.val());
        if(!formFound && e.parents('form').length > 0)
        {
          formFound = true;
          formE = e.parents('form');
        }
        if(indexId.test(id))
        {
          var p = id.indexOf('['),
              id1 = id.substr(0, p);
          if(e.is(':checked'))
          {
            if(typeof(checks[id1]) == 'undefined')
              checks[id1] = {};
            checks[id1][id.substr(p).replace(/\[|\]/g, '')] = v;
          }
          else if(e.hasClass('required'))
            requiredA[id1] = id;
          return;
        }
        if(e.is(':checked'))
          vals[id] = v;
        else if(e.hasClass('required'))
          err = error(e, id, 'frmVRequired');
    });
    $.each(requiredA, function(i, id) {
       if(typeof(checks[i]) == 'undefined')
         err = error(null, i, 'frmVRequired');
    });
    jQuery.extend(vals, checks);
    vals['__empties'] = nulls.join(',');
    if(typeof(formE) != 'undefined')
      $(formE).children('.__empties').length>0?
        $(formE).children('.__empties').val(vals['__empties']):
        $(formE).append('<input type="hidden" class="__empties" name="__empties" value="'+
            vals['__empties']+'" />');
    return err? false: vals;
  },
  /* search: jquery selector */
  searchPack: function(form)
  {
    form = typeof(form)=='undefined'? '': form+' ';
    var pack  = {},
        dVals = {};
    /* DATE */
    $(form+'.date').each(function() {
        var e = $(this),
            v = jQuery.trim(e.val());
        if(v && Arta.reg('d', v))
          dVals[e.attr('id')] = 'DATE'+v;
    });
    /* DATETIME/DATE/TIME */
    $(form+'.datetime, '+form+' .timepick').each(function() {
        var id = $(this).attr('id'),
            tH = $('#'+id+'_H').length? parseInt(jQuery.trim($('#'+id+'_H').val()), 10): 0,
            tM = $('#'+id+'_M').length? parseInt(jQuery.trim($('#'+id+'_M').val()), 10): 0,
            tS = $('#'+id+'_S').length? parseInt(jQuery.trim($('#'+id+'_S').val()), 10): 0,
            tD = jQuery.trim($('#'+id+'_date').val());
        if(tH || tM || tS)
          tD = jQuery.trim(tD+' '+tH+':'+tM+':'+tS);
        if(!tD)
          return;
        if(Arta.reg('d', tD))       dVals[id] = 'DATE'+tD;
        else if(Arta.reg('t', tD))  dVals[id] = 'TIME'+tD;
        else if(Arta.reg('dt', tD)) dVals[id] = tD;
        $(this).val(tD);
    });
    /* crawl */
    $(form+"input.search-form-widget[type!='radio'][type!='checkbox'], "+form+'select.search-form-widget, '+
      form+'textarea.search-form-widget, '+form+'.datetime, '+form+'.timepick').not('.ignore').each(function() {
        var e   = $(this),
            id  = e.attr('id'),
            idJ = '#'+id;
            v   = e.val(),
            isObj = typeof(v)=='object',
            isTime = e.hasClass('date') || e.hasClass('timepick') || e.hasClass('datetime');
        v = isObj? v: jQuery.trim(v);
        /* dont bother */ 
        if((!isObj && v == '') || v == null || (isObj && !v.length) || typeof(id) == 'undefined' ||
          !id || (isTime && typeof(dVals[id]) == 'undefined'))
          return;
        /* SEARCH OPERATOR */
        switch($(idJ+'-operator').val())
        {
          /* EQUAL > all */
          case 'E':
            if(e.hasClass('text') || e.hasClass('char')) v = [['AND', [[v, '=']]]];
            else if(e.hasClass('int'))   v = parseInt(v, 10);
            else if(e.hasClass('float')) v = parseFloat(v);
            else if(isTime)              v = dVals[id];
            pack[id] = v;
            break;
          /* CONTAIN > text */
          case 'C':
            if(!isObj) pack[id] = v;
            break;
          /* CONTAIN_ALL */
          case 'A':
            if(isObj) break;
            v = v.split(',');
            var vals = []; 
            $.each(v, function(i, val) { vals.push([val, 'LIKE']); });
            pack[id] = [['AND', vals]];
            break;
          /* CONTAIN_ONE */
          case 'O':
            if(isObj) break;
            v = v.split(',');
            var vals = []; 
            $.each(v, function(i, val) { vals.push([val, 'LIKE']); });
            pack[id] = [['OR', vals]];
            break;
          /* EQUAL_NOT > number */
          case 'N':
            if(isObj) break;
            if(e.hasClass('int'))        v = parseInt(v, 10);
            else if(e.hasClass('float')) v = parseFloat(v);
            pack[id] = [['AND', [[v, '<>']]]];
            break;
          /* GREATER LESS > number, date time */
          case 'G':
            if(isObj) break;
            if(e.hasClass('int'))        pack[id] = [['AND', [[parseInt(v, 10), '>']]]];
            else if(e.hasClass('float')) pack[id] = [['AND', [[parseFloat(v), '>']]]];
            else if(isTime)              pack[id] = [[dVals[id], '']];
            break;
          case 'L':
            if(isObj) break;
            if(e.hasClass('int'))        pack[id] = [['AND', [[parseInt(v, 10), '<']]]];
            else if(e.hasClass('float')) pack[id] = [['AND', [[parseFloat(v), '<']]]];
            else if(isTime)              pack[id] = [['', dVals[id]]];
            break;
          /* IN > all */
          case 'I':
            if(!isObj)
              v = v.split(',');
            if(e.hasClass('int'))
              $.each(v, function(i, val) { v[i] = parseInt(val, 10); });
            else if(e.hasClass('float'))
              $.each(v, function(i, val) { v[i] = parseFloat(val); });
            pack[id] = e.hasClass('select') || e.hasClass('multiselect')?
                {id: [['IN', v]]}: [['IN', v]];
            break;
          /* BETWEEN > number, date time */
          case 'B':
            if(isObj) break;
            var v2 = $(idJ+'-x').val();
            if(e.hasClass('int'))
              pack[id] = [['AND', [[parseInt(v, 10), '>='], [parseInt(v2, 10), '<=']]]];
            else if(e.hasClass('float'))
              pack[id] = [['AND', [[parseFloat(v), '>='], [parseFloat(v2), '<=']]]];
            else if(isTime && typeof(dVals[id+'-x']) != 'undefined')
              pack[id] = [[dVals[id], dVals[id+'-x']]];
            break;
          default:
            if(!$(this).hasClass('time'))
              pack[id] = v;
        }
    });
    /* checkboxes */
    $(form+"input[type='checkbox']").not('.ignore').each(function() {
        var e = $(this);
        pack[e.attr('id')] = e.is(':checked');
    });
    /* options */
    $(form+"input[type='radio']").not('.ignore').each(function() {
        var e = $(this);
        if(e.is(':checked'))
          pack[e.attr('name')] = jQuery.trim(e.val());
    });
    return pack;
  },
  /* search form - operator change */
  searchOperator: function(e)
  {
    var id = '#'+$(e).attr('id').replace('-operator', ''),
        idx = id+'-x';
    if($(id).hasClass('datetime'))
      idx = idx+'_date, '+idx+'_H, '+idx+'_M, '+idx+'_S';
    if($(id).hasClass('timepick'))
      idx = idx+'_H, '+idx+'_M, '+idx+'_S';
    $(e).val() == 'B'? $(idx).show(): $(idx).hide();
  },
  /* show/hide loading icon */
  loading: function(show)
  {
    if(show)
    {
      ++Arta.busy;
      $('#loading-icon').show();
    }
    else if(--Arta.busy < 1)
      $('#loading-icon').hide('slow');
  },
  /* Injects js and css into context */
  inject: function(css, js)
  {
    var h = $('head');
    if(typeof(css) != 'undefined')
      $.each(css, function(k, v) {
          if($("link[href='"+v+"']").length == 0)
            return;
          var e = document.createElement('link');
          e.href = v;
          e.rel = 'stylesheet';
          e.type = 'text/css';
          e.media = 'screen';
          h.append(e);
      });
    if(typeof(js) != 'undefined')
      $.each(js, function(k, v) {
          if($("script[src='"+v+"']").length > 0)
            return;
          var e = document.createElement('script');
          e.type = 'text/javascript';
          e.src = v;
          h.append(e);
      });
  },
  /* Arta ajax calls */
  ajax: function (url, data, method, onSuccess, onError, retry)
  {
    Arta.loading(true);
    var errF = function(err) {
      Arta.loading(false);
      if(typeof(onError) == 'function')
        return onError(err);
      else if(typeof(DEBUG) != 'undefined' && DEBUG)
        return Arta.msg(i18n.ajaxDebugTitle, err, 600, 500);
      else if(typeof(retry) == 'undefined')
        return Arta.ajax(url, data, method, onSuccess, onError, 1);
      else
        Arta.msg(i18n.ajaxDebugTitle, '<p>'+i18n.ajaxDebugMsg+'</p>', 400, 300);
    };
    data = typeof(data)=='object' && data!==null? data: {};
    data['__artaajax'] = 1;
    Arta.lastAccessTime = new Date();
    $.ajax({
        url: url.indexOf(BASE_URL)===0? url: BASE_URL+url,
        data: data,
        type: typeof(method)=='undefined'? 'post': method,
        success: function(oJ) {
          if(typeof(oJ) == 'object')
          {
            var hasArta = typeof(oJ.arta)!='undefined' && typeof(oJ.arta.resources)!='undefined';
            if(hasArta)
              Arta.inject(oJ.arta.resources.style, oJ.arta.resources.js);
            if(typeof(oJ.vals) == 'object')
              $.each(oJ.vals, function(id, v) {
                  $('#'+id).val(v);
              });
            if(typeof(oJ.html) == 'object')
              $.each(oJ.html, function(id, html) { $('#'+id).html(html); });
            if(typeof(oJ['html-append']) == 'object')
              $.each(oJ['html-append'], function(id, html) { $('#'+id).append(html); });
            if(typeof(oJ['html-prepend']) == 'object')
              $.each(oJ['html-prepend'], function(id, html) { $('#'+id).prepend(html); });
            if(typeof(onSuccess) == 'function')
              onSuccess(oJ);
            Arta.loading(false);
            if(typeof(oJ.msg) != 'undefined')
              Arta.msg(oJ.msg[0], '<p>'+oJ.msg[1]+'</p>', 350, 200);
            if(hasArta && typeof(oJ.arta.resources.js_code) != 'undefined')
              eval(oJ.arta.resources.js_code);
            if(typeof(oJ.debug) != 'undefined')
              inspect(oJ);
          }
          else
            errF(oJ);
        },
        error: function(jqXHR, textStatus, errorThrown) {
          errF(textStatus);
        }
    });
    return false;
  }
};
/** 
 * Arta inspect js vars
 */
function inspect()
{
  var inspector = function (obj, ident) {
    var typ = typeof(obj), oTyp = 'DICTIONARY {\n', oBrac = '}';
    if(typ === 'object') {
      if(obj) {
        if(typeof(obj.length) === 'number' && !(obj.propertyIsEnumerable('length')) &&
            typeof(obj.splice) === 'function') {
          oTyp = 'LIST [\n';
          oBrac = ']';
        }
      }
      else
        typ = 'null';
    }
    switch(typ) {
      case 'null':      return 'null';
      case 'number':    return 'number '+obj;
      case 'string':    return 'string "'+obj+'"';
      case 'boolean':   return 'boolean '+obj;
      case 'undefined': return 'undefined';
      case 'function':  return 'function';
      case 'xml':       return 'xml';
      case 'object':
        var ident2 = ident+'        ';
        var strA = [];
        $.each(obj, function(k, v) { strA.push(ident2+k+': '+inspector(v, ident2)); });
        //for(k in obj)
          //strA.push(ident2+k+': '+inspector(obj[k], ident2));
        return oTyp+strA.join(',\n')+'\n'+ident+oBrac;
    }
  }
  var text = '';
  var i, l=arguments.length;
  for(i=0; i<l; ++i)
    text += inspector(arguments[i], '')+"\n";
  alert(text);
}

