
var $j = jQuery.noConflict();

/* --------------------------------------------------------
   Namespace
-------------------------------------------------------- */

if (typeof TIBI == 'undefined') {
  TIBI = {};
}

TIBI.namespace = function(arg) {
  var ns = String(arg);
  if (!ns.length) { return null; }
  var levels = ns.split('.');
  var currentNS = TIBI;
  for (var i=(levels[0] == 'TIBI') ? 1 : 0; i < levels.length; i++) {
    currentNS[levels[i]] = currentNS[levels[i]] || {};
    currentNS = currentNS[levels[i]];
  }
  return currentNS;
};

TIBI.namespace('info');
TIBI.info = {
  blogUrl: 'http://blog.tibi.com'
};

TIBI.namespace('util');
TIBI.util = {

  buttonSubmit: function(that, formId) {
    that.blur();
    var form = $j('#'+formId)[0];
    if (form.onsubmit) {form.onsubmit();}
    form.submit();
  },

  setInputDefault: function(input, defValue, color, defColor) {
    if (!input)    { return; }
    if (!color)    { color = '#c9c9c9'; }
    if (!defColor) { defColor = '#333'; }

    if ($j.trim(input.val()) == "") {
      input.val(defValue);
      input.css('color', color);
    }
    input.focus(function() {
      if (input.val() == defValue) {
        input.val("");
      }
      input.css('color', defColor);
    });
    input.blur(function() {
      if ($j.trim(input.val()) == "") {
        input.val(defValue);
        input.css('color', color);
      } else {
        input.css('color', defColor);
      }
    });
  },

  resetForm: function(formId) {
    var obj = $j('#'+formId);
    $j(':input', obj).each(function(){
      var type = this.type;
      var tag  = this.tagName.toLowerCase();
      if (type == 'text' || type == 'password' || tag == 'textarea') {
        this.value = '';
      } else if (type == 'checkbox' || type == 'radio') {
        this.checked = false;
      } else if (tag == 'select') {
        this.selectedIndex = 0;
      }
    });
  },

  submitByReturn: function(e, form, callback) {
    var key = e ? (e.which ? e.which : e.keyCode) : event.keyCode;
    if (key == 13) {
      if (callback) {callback();}
      var form = $j('#'+form)[0];
      if (form.onsubmit) {form.onsubmit();}
      form.submit();
    }
  },

  checkCapsLock: function(e) {
    var key = e ? (e.which ? e.which : e.keyCode) : event.keyCode;
    var msg = 'Caps Lock is On.\n\nTo prevent entering the password ' +
              'incorrectly,\nyou should press Caps Lock to turn it off.';
    if ( ((key >= 65 && key <= 90)  && !e.shiftKey) ||   // upper case, no shift
         ((key >= 97 && key <= 122) &&  e.shiftKey) )    // lower case w/shift
      { alert(msg); }
  },

  onReturn: function(e, callback) {
    if (!callback) { return; }
    var key = e ? (e.which ? e.which : e.keyCode) : event.keyCode;
    if (key == 13) { callback(); }
  },

  formatCurrency: function(arg) {
    var num = arg.toString().replace(/\$|\,/g,'');
    if (isNaN(num)) { num = '0'; }
    var sign = (num == (num = Math.abs(num)));
    num = Math.floor(num*100+0.50000000001);
    var cents = num % 100;
    num = Math.floor(num/100).toString();
    if (cents < 10) { cents = '0' + cents; }
    for (var i=0; i < Math.floor((num.length-(1+i))/3); i++) {
      num = num.substring(0,num.length-(4*i+3))+','+
                            num.substring(num.length-(4*i+3));
    }
    return (((sign)?'':'-') + num + '.' + cents);
  },

  asCurrency: function(num) {
    var value = String(num).replace(/[^\d\.]+/g,'');
    var pos = value.lastIndexOf('.');
    var dec = '', whole='', newval='';
    if (pos != -1) {
      pos++;
      dec = value.substring(pos, value.length);
      if (dec.length > 2) {
        dec = dec.substring(0,2);
      } else if (dec.length < 2) {
        while (dec.length < 2) { dec += '0'; }
      }
      whole = value.substring(0, pos - 1);
    } else {
      whole = value;
      dec = '00';
    }
    for (var i=0; i < whole.length; i++) {
      newval = whole.substring(whole.length-i-1, whole.length-i) + newval;
    }
    if (newval == '') { newval = '0'; }
    return(newval + '.' + dec);
  },

  autoCurrency: function(field) {
    var value = String($j(field).val()).replace(/[^\d\.]+/g,'');
    if ((value == '') || isNaN(value)) { 
      $j(field).val(''); // delete non-numeric values
      return;
    }
    $j(field).val(TIBI.util.asCurrency(value));
  },

  scrollToElement: function(id) {
    var x=0, y=0;
    var elem = $j('#'+id)[0];
    if (!elem) { return; }
    while (elem != null) {
      x += elem.offsetLeft;
      y += elem.offsetTop;
      elem = elem.offsetParent;
    }
    window.scrollTo(x,y);
  },

  elementExists: function(elem) {
    if ((typeof(elem) == 'undefined') || (elem == null) ) {return false;}
    if ((typeof(elem) != 'object')    || !elem.length)    {return false;}
    return( (elem.length > 0) ? true : false);
  },

  arrayIncludes: function(ary, val) {
    var ret = false;
    $j.each(ary, function(i, v){
      if (val == v) { ret = true; }
    });
    return ret;
  },

  getElementsByTagAndClassName: function(className, tagName) {
    if (null == tagName) {
      tagName = '*';
    }
    var children = document.getElementsByTagName(tagName) || document.all;
    if (null == children || 0 == children.length) {
      return [];
    }
    var elements = [];
    if (className == null) {
      return children;
    }
    for (var i=0; i < children.length; i++) {
      var child = children[i];
      var classNames = child.className.split(' ');
      for (var j=0; j < classNames.length; j++) {
        if (classNames[j] == className) {
          elements.push(child);
          break;
        }
      }
    }
    return elements;
  },

  copyToClipboard: function(text) {
    // IE only
    if (window.clipboardData) {  
      window.clipboardData.setData('text',text);
      return true;
    }
    return false;
  }
  
}; // TIBI.util

$j('input.currency').blur(function(){TIBI.util.autoCurrency(this);});


/* --------------------------------------------------------
   Class
-------------------------------------------------------- */

var Class = {
  extend: function(parent, def) {
    if (arguments.length == 1) def = parent, parent = null;
    var func = function() {
      if (!Class.extending) this.initialize.apply(this, arguments);
    };
    if (typeof(parent) == 'function') {
      Class.extending = true;
      func.prototype = new parent();
      delete Class.extending;
    }
    var mixins = [];
    if (def && def.include) {
      if (def.include.reverse) {
        // methods defined in later mixins should override prior
        mixins = mixins.concat(def.include.reverse());
      } else {
        mixins.push(def.include);
      }
      delete def.include; // clean syntax sugar
    }
    if (def) Class.inherit(func.prototype, def);
    for (var i = 0; (mixin = mixins[i]); i++) {
      Class.mixin(func.prototype, mixin);
    }
    return func;
  },

  mixin: function (dest) {
    for (var i = 1; (src = arguments[i]); i++) {
      if (typeof(src) != 'undefined' && src !== null) {
        for (var prop in src) {
          if (!dest[prop] && typeof(src[prop]) == 'function') {
            // only mixin functions, if they don't previously exist
            dest[prop] = src[prop];
          }
        }
      }
    }
    return dest;
  },

  inherit: function(dest, src, fname) {
    if (arguments.length == 3) {
      var ancestor = dest[fname], descendent = src[fname], method = descendent;
      descendent = function() {
        var ref = this.parent; this.parent = ancestor;
        var result = method.apply(this, arguments);
        ref ? this.parent = ref : delete this.parent;
        return result;
      };
      // mask the underlying method
      descendent.valueOf = function() { return method; };
      descendent.toString = function() { return method.toString(); };
      dest[fname] = descendent;
    } else {
      for (var prop in src) {
        if (dest[prop] && typeof(src[prop]) == 'function') {
          Class.inherit(dest, src, prop);
        } else {
          dest[prop] = src[prop];
        }
      }
    }
    return dest;
  }
};

Class.create = function() {
  return Class.extend.apply(this, arguments);
};


/* --------------------------------------------------------
   Environment
-------------------------------------------------------- */

var Env = {
  windowSize: function() {
    var d = document.documentElement;
    var w = (window.innerWidth    || 
             self.innerWidth      || 
             (d && d.clientWidth) || 
             document.body.clientWidth);
    var h = (window.innerHeight    ||
             self.innerHeight      ||
             (d && d.clientHeight) ||
             document.body.clientHeight);
    return {width:w,height:h};
  },

  scrollPos: function() {
    if (self.pageYOffset !== undefined) {
      return {x:self.pageXOffset, y:self.pageYOffset};
    }
    var d = document.documentElement;
    return {x:d.scrollLeft, y:d.scrollTop};
  }
}; // Env

/* --------------------------------------------------------
  Plugins
-------------------------------------------------------- */

// $("#thing-that-will-become-rounded").roundThis("20px");
jQuery.fn.roundThis = function(radius) {
  return this.each(function(e) {
    $j(this).css({
      "border-radius": radius,
      "-moz-border-radius": radius,
      "-webkit-border-radius": radius
    });
  });
};

jQuery.fn.formToDict = function() {
  var h={}, ary = this.serializeArray();
  for (var i=0; i < ary.length; i++) {
    h[ary[i].name] = ary[i].value;
  }
  return h;
};

jQuery.fn.disable = function() {
  this.attr('disabled','disabled');
  return this;
};

jQuery.fn.enable = function(arg) {
  if (arguments.length && !arg){
    this.attr('disabled','disabled');
  } else {
    this.removeAttr('disabled');
  }
  return this;
};

jQuery.fn.center = function(widthBuf, heightBuf, flush){
  var win = Env.windowSize();
  var scrollPos = flush ? {x:0, y:0} : Env.scrollPos();
  for (var i=0; i < this.length; i++){
    var wOffset = Math.max(0, win.width-this[i].offsetWidth);
    var hOffset = Math.max(0, win.height-this[i].offsetHeight);
    $j(this[i]).css({
      top: scrollPos.y + hOffset*(heightBuf !== undefined ? heightBuf : 0.5),
      left:scrollPos.x + wOffset*(widthBuf !== undefined ? widthBuf : 0.5)
    });
  }
  return this;
};

