var tom = {
  VERSION: "3.0.1",
  COPYRIGHT: "www.tom.com",
  AUTHOR: "wudi msn:woodlessr@hotmail.com blog:http://blog.tom.com/woodless;",
  fnEmpty: function() {},
  fnTrue: function() { return true; },
  fnFalse: function() { return false; }
};

tom.config = {
  Alert: {
  	_fnCallBack: function(msg, ico, fn, autoHide) {
  	  var cb = fn ? ((fn instanceof Function) ? fn : ((typeof(fn) == "string") ? new Function("e", fn) : tom.fnTrue)) : tom.fnTrue;
      alert(msg);
      cb();
  	},
  	getCallBack: function() {
  	  return this._fnCallBack;
  	}
  },
  Information: {
  	_fnCallBack: function(msg, autoHide, fn) {
      var cb = fn ? ((fn instanceof Function) ? fn : ((typeof(fn) == "string") ? new Function("e", fn) : tom.fnTrue)) : tom.fnTrue;
      alert(msg);
      cb();
  	},
  	getCallBack: function() {
  	  return this._fnCallBack;
  	}
  },
  Confirm: {
  	_fnCallBack: function(msg, fnOk, fnCancel, title) {
      var cbOk = fnOk ? ((fnOk instanceof Function) ? fnOk : ((typeof(fnOk) == "string") ? new Function("e", fnOk) : tom.fnTrue)) : tom.fnTrue;
      var cbCancel = fnCancel ? ((fnCancel instanceof Function) ? fnCancel : ((typeof(fnCancel) == "string") ? new Function("e", fnCancel) : tom.fnTrue)) : tom.fnTrue;
      confirm(msg) ? cbOk() : cbCancel();
  	},
  	getCallBack: function() {
  	  return this._fnCallBack;
  	}
  },
  Login: {
  	_fnCallBack: function(backUrl) {
      alert("TODO. back to " + backUrl);
  	},
  	getCallBack: function() {
  	  return this._fnCallBack;
  	}
  }
};

tom.Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
};

if (typeof($) == 'undefined') {
  $ = function(elem) {
    if (arguments.length > 1) {
      for (var i = 0, elems = [], length = arguments.length; i < length; i++)
        elems.push($(arguments[i]));
      return elems;
    }
    if (typeof elem == 'string') {
      return document.getElementById(elem);
    } else {
    	return elem;
    }
  };
}

if (typeof($A) == 'undefined') {
  $A = function(a) {
    var results = [];
    for (var i = 0, length = a.length; i < length; i++) {
      results.push(a[i]);
    }
    return results;
  };
}

tom.extend = function(dist) {
  var srcs = $A(arguments);
  srcs.splice(0, 1);
  for (var i = 0; i < srcs.length; i++) {
    var src = srcs[i];
    for (var p in src) {
      dist[p] = src[p];
    }
  }
  return dist;
}

tom.extend(
  String.prototype,
  {
  	trim: function() {
      return this.replace(/^\s+|\s+$/g, "");
    },
    startsWith: function(pf) {
      return pf == "" ? true : this.indexOf(pf) == 0;
    },
    endsWith: function (sf) {
      return sf == "" ? true : this.lastIndexOf(sf) == this.length - String(sf).length;
    }
  }
);


tom.Event = {
  addEvent: function(elem, name, fn, useCapture) {
    if (elem.addEventListener) {
      elem.addEventListener(name, fn, useCapture);
    } else if (elem.attachEvent) {
      elem.attachEvent('on' + name, fn);
    }
  },
  removeEvent: function(elem, name, fn, useCapture) {
    if (elem.removeEventListener) {
      elem.removeEventListener(name, fn, useCapture);
    } else if (elem.detachEvent) {
      elem.detachEvent('on' + name, fn);
    }
  },
  pointer: function(e) {
    return {x: this.pointerX(e), y: this.pointerY(e)};
  },
  pointerX: function(e) {
    return e.pageX || (e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
  },
  pointerY: function(e) {
    return e.pageY || (e.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
  },
  stop: function(e) {
    if (e.preventDefault) {
      e.preventDefault();
      e.stopPropagation();
    } else {
      e.returnValue = false;
      e.cancelBubble = true;
    }
  },
  isLeftClick: function(e) {
    return (((e.which) && (e.which == 1)) || ((e.button) && (e.button == 1)));
  }
};

tom.Position = {
  getWindowClientWidth: function() {
    return window.innerWidth 
        || document.documentElement.clientWidth
        || document.body.clientWidth
        || 0;
  },
  getWindowClientHeight: function() {
    return window.innerHeight 
        || document.documentElement.clientHeight
        || document.body.clientHeight
        || 0;
  },
  getWindowScrollWidth: function() {
    return window.scrollWidth 
        || document.documentElement.scrollWidth
        || document.body.scrollWidth;
  },
  getWindowScrollHeight: function() {
    return window.scrollHeight
        || document.documentElement.scrollHeight
        || document.body.scrollHeight;
  },
  getWindowScrollLeft: function() {
    if (window.scrollWidth) {
      return window.scrollLeft;
    } else if (document.documentElement.scrollWidth) {
      return document.documentElement.scrollLeft;
    } else if (document.body.scrollWidth) {
      return document.body.scrollLeft
    } else {
      return 0;
    }
  },
  getWindowScrollTop: function() {
    if (window.scrollWidth) {
      return window.scrollTop;
    } else if (document.documentElement.scrollWidth) {
      return document.documentElement.scrollTop;
    } else if (document.body.scrollWidth) {
      return document.body.scrollTop;
    } else {
      return 0;
    }
  }
};

tom.Image = {
  resizeImage: function(img, mw, mh) {
    var w = img.offsetWidth;
    var h = img.offsetHeight;
    if (w / h >= mw / mh) {
      if (w >= mw) {
	    img.style.width = mw + "px";
	  }
    } else {
      if (h >= mh) {
        img.style.height = mh + "px";
	  }
    }
  }
};
/**
 * package tom.util
 */
tom.util = {};
tom.util.List = tom.Class.create();
tom.extend(tom.util.List.prototype, {
  initialize: function() {
    this._l = [];
  },
  add: function(o) { this._l.push(o); },
  addAll: function(l) {
  	var a = (l instanceof tom.util.List || l instanceof tom.util.Set) ? l._l : l;
  	for (var i = 0; i < a.length; i++) {
  	  this._l.push(a[i]);
  	}
  },
  clear: function() { this._l.length = 0; },
  contains: function(o) { return this.indexOf(o) != -1; },
  get: function(i) { return this._l[i]; },
  indexOf: function(o) {
    for(var i = 0; i < this._l.length; i++){
      if(this._l[i] === o) {
        return i;
      }
    }
    return -1;
  },
  isEmpty: function() { return this._l.length == 0; },
  remove: function(i) { return this._l.splice(i, 1); },
  removeObject: function(o) { 
    var i = this.indexOf(o);
    if (i != -1) {
      return this._l.splice(i, 1)[0]; 
    } else {
      return null;
    }
  },
  size: function() { return this._l.length; },
  toArray: function() { return [].concat(this._l); },
  dump: function() { return "[" + this._l.join(",") + "]"; },
  sort: function(fn) {
  	if (!this._l || this._l.length < 2) {
  	  return this;
  	}
  	if (fn) {
  	  this._l.sort(fn);
  	} else {
  	  this._l.sort();
  	}
  	return this;
  },
  filter: function(fnExp, fnCond) {
    return tom.util.Arrays.asList(tom.util.Arrays.filter(fnExp, this._l, fnCond));
  },
  each: function(fn) {
  	var l = this._l;
  	for (var i = 0, len = l.length; i < len; i++) {
  	  fn(l[i]);
  	}
  }
});
tom.util.Set = tom.Class.create();
tom.extend(tom.util.Set.prototype, tom.util.List.prototype, {
  initialize: function() {
    this._l = [];
  },
  add: function(o) {
    if (this.indexOf(o) == -1) {
      this._l.push(o);
    }
  },
  addAll: function(s) {
  	var a = (s instanceof tom.util.List || s instanceof tom.util.Set) ? s._l : s;
    for (var i = 0; i < a.length; i++) {
      this.add(a[i]);
    }
  },
  filter: function(fnExp, fnCond) {
    return tom.util.Arrays.asSet(tom.util.Arrays.filter(fnExp, this._l, fnCond));
  }
});
tom.util.Map = tom.Class.create();
tom.extend(tom.util.Map.prototype, {
  initialize: function() {
    this._m = {};
  },
  clear: function() { this._m = {}; },
  containsKey: function(k) { return this._m.hasOwnProperty("_" + k); },
  containsValue: function(v) {
    for (var k in this._m) {
      if (this._m["_" + k] === v) {
        return true;
      }
    }
    return false;
  },
  get: function(k) { return this._m["_" + k]; },
  isEmpty: function() {
    for (var k in this._m) {
      return false;
    }
    return true;
  },
  keySet: function() {
  	var set = new tom.util.Set();
    var m = this._m;
    for (var i in m) {
      set.add(i);
    }
    return set;
  },
  values: function() {
  	var a = [];
    var m = this._m;
    for (var i in m) {
      a.push(m[i]);
    }
    return tom.util.Arrays.asList(a);
  },
  put: function(k, v) { return this._m["_" + k] = v; },
  remove: function(k) {
    var v = this._m["_" + k];
    delete(this._m["_" + k]);
    return v;
  },
  size: function() {
    var c = 0;
    for (var i in this._m) {
      c++;
    }
    return c;
  },
  filter: function(fnExp, fnCond) {
    switch (typeof(fnExp)) {
      case "undefined":
        fnExp = function(k, v) { return {k: k, v: v} };
        break;
      case "function": 
        break;
      case "string":
        fnExp = new Function("k", "v", "return " + fnExp + ";");
        break;
    }
    switch (typeof(fnCond)) {
      case "undefined":
        fnCond = tom.fnTrue;
        break;
      case "function": 
        break;
      case "string":
        fnCond = new Function("k", "v", "return (" + fnCond + ");");
        break;
    }
    
	var rst = new tom.util.Map();
	var m = this._m;
	var v = null;
    var t = null;
    for (var k in m) {
      v = m[k];
      k = k.substring(1, k.length);
      if (fnCond(k, v)) {
      	t = fnExp(k, v);
        rst.put(t.k, t.v);
      }
    }
    return rst;
  },
  each: function(fnExp, fnCond) {
    switch (typeof(fnExp)) {
      case "undefined":
        fnExp = function(k, v) { return {k: k, v: v} };
        break;
      case "function": 
        break;
      case "string":
        fnExp = new Function("k", "v", "return " + fnExp + ";");
        break;
    }
    switch (typeof(fnCond)) {
      case "undefined":
        fnCond = tom.fnTrue;
        break;
      case "function": 
        break;
      case "string":
        fnCond = new Function("k", "v", "return (" + fnCond + ");");
        break;
    }
	var m = this._m;
	var v = null;
    for (var k in m) {
      v = m[k];
      k = k.substring(1, k.length);
      if (fnCond(k, v)) {
      	fnExp(k, v);
      }
    }
  }
});
tom.util.Queue = tom.Class.create();
tom.extend(tom.util.Queue.prototype, {
  initialize: function() {
    this._q = [];
  },
  enqueue: function(o) {
    this._q.push(o);
  },
  dequeue: function() {
    return this._q.shift();
  },
  peek: function() {
    return this._q[0];
  },
  size: function() {
    return this._q.length;
  }
});

tom.util.ActiveObject = tom.Class.create();
tom.extend(tom.util.ActiveObject.prototype, {
  initialize: function(period) {
  	this.period = period ? period : 100;
  	this.timer = null;
  	this.taskQueue = new tom.util.Queue();
  },
  start: function() {
  	var _this = this;
  	this.timer = setInterval(
  	  function() {
  	  	_this.execute();
  	  },
  	  this.period
  	)
  },
  stop: function() {
  	clearInterval(this.timer);
  },
  run: tom.fnEmpty,
  addTask: function(t) {
  	this.taskQueue.enqueue(t);
  }
});

tom.util.Arrays = {
  asList: function(a) {
    var l = new tom.util.List();
    l._l = [].concat(a);
    return l;
  },
  asSet: function(a) {
    var s = new tom.util.Set();
    for (var i = 0, len = a.length; i < len; i++) {
      s.add(a[i]);
    }
    return s;
  },
  asMap: function(a, asType) {
  	asType = asType ? asType : 0;
  	var m = new tom.util.Map();
  	for (var i = 0, len = a.length, v = null; i < len; i++) {
  	  v = a[i];
      switch (asType) {
        case 0:
          m.put(v[0], v[1]);
          break;
        case 1:
          m.put(v, a[++i]);
          break;
        case 2:
          m.put(v.k, v.v);
          break;
        default:
          break;
      }
  	}
  	return m;
  },
  filter: function(fnExp, arr, fnCond) {
    switch (typeof(fnExp)) {
      case "undefined":
        fnExp = function(o) { return o; };
        break;
      case "function": 
        break;
      case "string":
        fnExp = new Function("o", "return " + fnExp + ";");
        break;
    }
    switch (typeof(fnCond)) {
      case "undefined":
        fnCond = tom.fnTrue;
        break;
      case "function": 
        break;
      case "string":
        fnCond = new Function("o", "return (" + fnCond + ");");
        break;
    }
    var rst = [];
    var o = null;
    for (var i = 0, l = arr.length; i < l; i++) {
      o = arr[i];
      if (fnCond(o)) {
        rst.push(fnExp(o));
      }
    }
    return rst;
  }, 
  dump: function(a) {
    return a.join(",");
  }
};

/** XHConn - Simple XMLHTTP Interface - bfults@gmail.com - 2005-04-08        **
 ** Code licensed under Creative Commons Attribution-ShareAlike License      **
 ** http://creativecommons.org/licenses/by-sa/2.0/                           **/
/**
 * Modified at 2007-05-18 By woodless
 * Email: woodlessr@hotmail.com
 */
tom.XHConn = tom.Class.create();
tom.extend(tom.XHConn.prototype, {
  initialize: function() {
    this.xmlhttp = false;
    this.isComplete = false;
    try { this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
    catch (e) { try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
    catch (e) { try { this.xmlhttp = new XMLHttpRequest(); }
    catch (e) { this.xmlhttp = false; }}}
  },
  connectAsync: function(url, method, vars, callback) {
    if (!this.xmlhttp) return false;
    this.isComplete = false;
    try {
      if (method.toUpperCase() == "GET") {
        this.xmlhttp.open(method, url + "?" + vars, true);
        vars = "";
      } else {
        this.xmlhttp.open(method, url, true);
        this.xmlhttp.setRequestHeader("Method", "POST " + url + " HTTP/1.1");
        this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      }
      var _this = this;
      this.xmlhttp.onreadystatechange = function() {
        if (_this.xmlhttp.readyState == 4 && !_this.isComplete) {
          _this.isComplete = true;
          callback(_this.xmlhttp);
        }
      };
      this.xmlhttp.send(vars);
    } catch(z) {
    	alert(z.message);
    	return false;
    }
    return true;
  },
  connectSync: function(url, method, vars, options) {
    if (!this.xmlhttp) return false;
    options = options ? options : {text: true, xml: false, json: false};
    this.isComplete = false;
    method = method.toUpperCase();
    try {
      if (method == "GET") {
        this.xmlhttp.open(method, url + "?" + vars, false);
        vars = "";
      } else {
        this.xmlhttp.open(method, url, false);
        this.xmlhttp.setRequestHeader("Method", "POST " + url + " HTTP/1.1");
        this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      }
      this.xmlhttp.send(vars);
    } catch(e) {
    	alert(e.message);
    	return false;
    }
    var o = {};
    if (options.text) {
      o["text"] = this.xmlhttp.responseText;
    }
    if (options.xml) {
      o["xml"] = this.xmlhttp.responseXML;
    }
     if (options.json) {
      o["json"] = eval("(" + this.xmlhttp.responseText + ")");
    }
    return o;
  }
});
tom.XHConn.Parameter = Class.create();
tom.extend(tom.XHConn.Parameter.prototype, tom.util.Map.prototype, {
  initialize: function(m) {
  	m = m ? m : {};
  	tom.util.Map.prototype.initialize.apply(this, []);
  	tom.extend(this, m);
  },
  append: function(k, v) {
  	this.put(k, v);
  	return this;
  },
  stringValue: function() {
  	var m = this._m;
	var s = "";
  	var i = 0;
  	var v = null;
  	for (var k in m) {
  	  if (i++ > 0) {
  	  	s += "&";
  	  }
  	  v = m[k];
  	  k = k.substring(1, k.length);
  	  s += k + "=" + encodeURIComponent(v);
  	}
  	return s;
  }
});
tom.XHConn.parseResult = function(xhq, options) {
  var opt = {};
  tom.extend(
    opt,
    { text: true, xml: false, json: false},
    options || {}
  );
  var o = {};
  if (opt.text) {
    o["text"] = xhq.responseText;
  }
  if (opt.xml) {
    o["xml"] = xhq.responseXML;
  }
  if (opt.json) {
    o["json"] = eval("(" + xhq.responseText + ")");
  }
  return o;
}
tom.XHConn.quickFillGet = function(fillId, url, vars) {
  var xhc = new XHConn();
  xhc.connectAsync(
    url, 
    "get", 
    vars ? vars : "", 
    function(xhq) {
      $(fillId).innerHTML = xhq.responseText;
    });
}

/*
 * 提示框（类似Alert）
 * msg: 提示信息
 * ico：图标，OK/ERROR/INFO
 * fn: 关闭提示框后执行的回调函数。（可选）
 * autoHide: 自动关闭的时间，如不添则不自动隐藏。（可选）
 */
tom.Alert = function(msg, ico, fn, autoHide) {
  tom.config.Alert.getCallBack()(msg, ico, fn, autoHide);}

/*
 * 确认框（类似Alert）
 * msg: 提示信息
 * fnOk: 点击ok按钮的回调函数。
 * fnCancel: 点击cancel的回调函数。
 * title: 标题（可选）
 */
tom.Confirm = function(msg, fnOk, fnCancel, title) {
  tom.config.Confirm.getCallBack()(msg, fnOk, fnCancel, title);
}

/*
 * 提示框（只是一个div）
 * msg: 提示信息
 * autoHide: 自动关闭的时间，如不添则不自动隐藏。
 * fn: 关闭提示框后执行的回调函数。（可选）
 */
tom.Information = function(msg, autoHide, fn) {
  tom.config.Information.getCallBack()(msg, autoHide, fn);
}

tom.Waiting = function() {
	
}
tom.Waiting.hide = function() {
	
}

/*
 * 登录框（div）
 * todo
 */
tom.Login = function(backUrl) {
  tom.config.Login.getCallBack()(backUrl);
}
tom.Login.onSubmit = function() {
  var tomid = $("post_login_tomid");
  var tompwd = $("post_login_tompwd");
  if (tomid.value.trim() == "") {
    alert("请输入用户名");
    return false;
  } else if (!/^(\d|[a-zA-Z])+(-|\.|\w)*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(tomid.value.trim())) {
    alert("请输入正确格式用户名");
    return false;
  }
  
  if (tompwd.value.trim() == "") {
    alert("请输入密码");
    return false;
  }
  return true;
}
tom.Login.autoCompleteUserId = function() {
  var tomid	= $("post_login_tomid").value.trim();
  var constant = "@tom.com";
  if (tomid.length > 0 && tomid.indexOf("@") == -1) {
    $("post_login_tomid").value = tomid + constant;
  }
  return;
}

