
//
// Browser Compatibilty

var detectBrowser = function() {
	var agent = navigator.userAgent.toLowerCase();
	var version = (agent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1];

	var safari = false;
	var opera = false;
	var ie = false;
	var mozilla = false;
	var gecko = false;

	if (/webkit/.test(agent))
		safari = true;
	if (/opera/.test(agent))
		opera = true;
	if (/msie/.test(agent) && !/opera/.test(agent))
		ie = true;
	if (/mozilla/.test(agent) && !/(compatible|webkit)/.test(agent))
		mozilla = true;
	if (/gecko/.test(agent))
		gecko = true;

	return {
		"safari":  safari,
		"opera":   opera,
		"ie":      ie,
		"mozilla": mozilla,
		"gecko":   gecko,
		"version": version
	};
};

var detectOS = function() {
	var agent = navigator.userAgent.toLowerCase();

	return {
		"windows" : /win/.test(agent),
		"mac" : /mac/.test(agent),
		"linux" : /linux/.test(agent),
		"unix" : /x11/.test(agent)
	}
};

var USER_BROWSER = detectBrowser();
var USER_OS = detectOS();





// from ProtoType library
var CallBack = function(object, func, args) {
	var _scope = object;
	var _fn = func;
	if (!args) args = [];
	return function() {
		return _fn.apply(_scope, args);
	};
};

var CallBackWithArguments = function(object, func) {
	var _scope = object;
	var _fn = func;
	return function() {
		args = arguments;
		return _fn.apply(_scope, args);
	};
}

// from son!!
var CallBackAsEventListener = function(object, func) {
	var _scope = object;
	var _fn = func;
	return function(event) {
		return _fn.apply(_scope, [event]);
	};
};

// Array
Array.prototype.contains = function (elem) {
  for (var i = 0; i < this.length; i++) {
	  if (this[i] === elem) {
	    return true;
	  }
  }
  return false;
};

Array.prototype.indexOf = function (item) {
	var ret=-1;
	for(var i = 0; i < this.length; i++) {
    if (this[i] == item) {
      ret=i; break;
    }
  }
	return(ret);
};


// Dec to Hex converter
var Dec2Hex = function(N) {
	if (N==null) return "00";
	N = parseInt(N);
	if (N==0 || isNaN(N)) return "00";
	N = Math.max(0, N);
	N = Math.min(N, 255);
	N = Math.round(N);
	
	return "0123456789ABCDEF".charAt((N-N%16)/16) + "0123456789ABCDEF".charAt(N%16);
}

var NormalizeColorCode = function(_color) {
	var _codes = _color.toLowerCase().match(/rgb\(\s*([0-9]*)\s*,\s*([0-9]*)\s*,\s*([0-9]*)\s*\)/);
	if (_codes) {
		return "#" + Dec2Hex(_codes[1]) + Dec2Hex(_codes[2]) + Dec2Hex(_codes[3]);
	}
	return _color;
};


// DOM class
//Element.prototype.addClass = function(_class) {
var addClassToElement = function(_element, _class) {
	if (_element && _class) {
		if (_element.className.match(_class)) {
		}
		else {
			_element.className = _element.className + " " + _class;
		}
	}
};

//Element.prototype.removeClass = function(_class) {
var removeClassToElement = function(_element, _class) {
	if (_element && _class) {
		_element.className = _element.className.replace(_class, "");
	}
};

// unixtime convertor
var unixTimeToDate = function(_unixtime) {
	var _ret = {};
 	var _ux = Math.floor(Number(_unixtime));
	var _date = new Date(_ux);
	var _new = _date.toUTCString();
	// delete comma next day(string)
	var _utc = _new.replace(/,/, '');
	_utc = _utc.split(" ");

	_ret["inputed"] = _unixtime;
	_ret["date"] = _new;
	_ret["year"] = _utc[3];
	_ret["month"] = DateFormatter.alpha_to_digit(_utc[2]);
	_ret["day"] = _utc[1];
	_ret["time"] = _utc[4];
	if(_ret.time) {
		var _hhmmss = _ret.time.split(":");
		_ret["hour"] = _hhmmss[0];
		_ret["minute"] = _hhmmss[1];
	}

	return _ret;
}

// string date convertor
var dateToUnixTime = function(_date) {
	// expect YYYY-MM-DD HH:MM
	var _d = _date.replace(/[^0-9]/gi, '|');
	_d = _d.replace(/\|+/gi, '|');
	_d = _d.split("|");
	var year = _d[0].replace(/^0/, '');
	var month = _d[1].replace(/^0/, '');
	var day = _d[2].replace(/^0/, '');
	var hour = _d[3].replace(/^0/, '');
	var min = _d[4].replace(/^0/, '');
	var _date_object = new Date(Date.UTC(year, month-1, day, hour, min));

	return _date_object.getTime();
}

// 
// EventListener
function add_event(_element, kindof_event, fn) {

	if (_element.addEventListener) {
		_element.addEventListener(kindof_event, fn, false);
		return true;
	} else if (_element.attachEvent) {
		var r = _element.attachEvent('on' + kindof_event, fn);
		return r;
	} else {
		_element['on' + kindof_event] = fn;
	}

}

// 
// RemoveListener
function remove_event(_element, kindof_event, fn) {
	if (_element.removeEventListener) {
		_element.removeEventListener(kindof_event, fn, false);
		return true;
	} else if (_element.detachEvent) {
		if(kindof_event == "blur") kindof_event = "focusout";
		var r = _element.detachEvent('on' + kindof_event, fn);
		return r;
	} else {
		_element['on' + kindof_event] = "";
	}
}

// return array key which point at received searching value
function array_search(haystack, searching_value, searching_key) {

	for(var _key in haystack) {
		if(typeof haystack[_key] == "object") {
			for(var __key in haystack[_key]) {
				if(haystack[_key][__key] == searching_value) {
					if(String(searching_key)) {
						if(__key == searching_key) {
							return [_key, __key];
						}
					} else {
						return [_key, __key];
					}
				}
			}
		} else {
			if(haystack[_key] == searching_value) {
				if(searching_key) {
					if(_key == searching_key) {
						return _key;
					}
				} else {
					return _key;
				}
			}
		}
	}
	return;
}

//
// Log
//

var Log = function(message) {
	var str = message;
	
	try {
		if (window.console && window.console.firebug) {
			// with Firebug
			console.debug(str);
			return;
		}
	} catch(e) {} // IE6: StrangeBehavior - exception when access members of window.console

	// without Firebug
	var e = $$('#DEBUG ol').first();

	if (e) {
		if (typeof(message) == 'object') {
			if (message.length) {
				str = $A(message).inspect();
			}
			else {
				str = "<pre>";
				$H(message).each(function(e){
					str += e.key + ": " + e.value + "<br />";
				});
				str += "</pre>";
			}
		}
		$(e).insert('<li>' + str + '</li>');
	}

};

// init Logger
Event.observe(window, "load", function(){

	try {
		if (window.console && window.console.firebug) {
			// ok
			// use firebug console
		}
	} catch(e) {
		// create the logging <div>
		$(document.body).insert('<div id="DEBUG"><ol></ol></div>');
	}
});


var StringRepeat = function(_s, _n) {
	var s = _s;
	for(var i=1; i<_n; i++) {
		s += (_s);
	}

	return s;
}

var ObjectSerialize = function(_o, _s) {

	if(!_s) _s = "=";

	var o = new Array();
	for(var _k in _o) o.push(_k + _s + _o[_k]);

	return o;
}

var Trim = function(s) {
	s = s.replace(/^\s+/, '');
	s = s.replace(/\s+$/, '');

	return s;
}

var ObjectLength = function(o) {
	var _count = 0;
		for(var idx in o) {
			_count++;
		}

	return _count;
}

function ObjectSplice(_o, _k) {
  var _r = {};
  for(var _i in _o) {
    if(_i == _k) continue;
    _r[_i] = _o[_i];
  }

  return _r;
}

function object_serialize(value, join_string) {

	if(!join_string) {
		join_string = ", ";
	}

	var values = new Array();
	for(var _key in value) {

		values.push(_key + "=" + value[_key]);
	}

	return values.join(join_string);
}

function object_length(hash) {

	var _count = 0;
	for(var idx in hash) {

		_count++;
	}

	return _count;
}

function ObjectCompare(_a, _b) {
	var a = $H(_a);
	var b = $H(_b);

	var ak = a.keys().join();
	var av = a.values().join();

	var bk = b.keys().join();
	var bv = b.values().join();

	return (ak == bk && av == bv);
}

//
function set_synki_title(_title) {
	document.title = "Synki: " + _title;
};



/* utils.js */
// as like add_event
function AddEvent(_element, kindof_event, fn) {

	if (_element.addEventListener) {
		_element.addEventListener(kindof_event, fn, false);
		return true;
	} else if (_element.attachEvent) {
		if(kindof_event == "blur") kindof_event = "focusout";
		var r = _element.attachEvent('on' + kindof_event, fn);
		return r;
	} else {
		_element['on' + kindof_event] = fn;
	}
}

// as like remove_event
function RemoveEvent(_element, kindof_event, fn) {
	if (_element.removeEventListener) {
		_element.removeEventListener(kindof_event, fn, false);
		return true;
	} else if (_element.detachEvent) {
		if(kindof_event == "blur") kindof_event = "focusout";
		var r = _element.detachEvent('on' + kindof_event, fn);
		return r;
	} else {
		_element['on' + kindof_event] = "";
	}
}

var CallBackAsEvent = function(object, func) {
	var _scope = object;
	var _fn = func;
	return function(event) {
		return _fn.apply(_scope, [event]);
	};
};

var ToArray = function(haystack) {
	var values = new Array();

	if(typeof haystack == "string") {

		values.push(haystack);
	} else {
		for(var _key in haystack) {
			values[_key] = haystack[_key];
		}
	}

	return values;
}

var MoveCenter = function(_element) {

  var wW = Math.max(document.documentElement.clientWidth, document.body.clientWidth);
  var wH = Math.max(document.documentElement.clientHeight, document.body.clientHeight);
  var wmH = Math.min(document.documentElement.clientHeight, document.body.clientHeight);
  var sT = Math.max(document.documentElement.scrollTop, document.body.scrollTop);

  var iH = _element.offsetHeight;
  var iW = _element.offsetWidth;

  var x_pos = (wW / 2) - (iW / 2);
	var y_pos = sT + 10;

  _element.style.top = y_pos + "px";
  _element.style.left = x_pos + "px";
}


/* memento */
// Trim
String.prototype.trim = function(){
	return this.replace(/^(\s|&nbsp;)+|(\s|&nbsp;)+$/g, "");
}
String.prototype.ltrim = function(){
	return this.replace(/^(\s|&nbsp;)+/g, "");
}
String.prototype.rtrim = function(){
	return this.replace(/(\s|&nbsp;)+$/g, "");
}

String.prototype.toCamalCase = function() {
	return this;
};

String.prototype.toSnakeCase = function() {
	var _str1 = this.replace(/[a-z]{1}([A-Z])/g, function(m,l) {return m.slice(0,1) + "_" + l.toLowerCase()});
	var _str2 = _str1.replace(/([A-Z])/g, function(m,l) {return l.toLowerCase()});
	return _str2;
};

// array acceptable without
Array.prototype._without = function() {
	var values = (arguments[0].constructor == [].constructor) ? arguments[0] : $A(arguments);
	return this.select(function(value) {
		return !values.include(value);
	});
};

/* page_link */
var PageLink = function(){
};

PageLink.join_us = function(){
	location.href = "/users/new";
	return false;
}

PageLink.my = function(){
	location.href = "/my";
	return false;
}

PageLink.workspace_root = function(){
	location.href = "/";
	return false;
}


// DOM Show/Hide Controller
var DisplayController = {
	select_dom: function(_id) {
		return document.getElementById(_id);
	},
	dom_display: function(_id) {
		return this.select_dom(_id).style.display;
	},

	is_show: function(_id) {
		return this.dom_display(_id) == "" && !this.hasClassName(_id, "Hide") || this.dom_display(_id) != "" && this.dom_display(_id) != "none";
	},
	is_hide: function(_id) {
		return this.dom_display(_id) == "none" || this.dom_display(_id) == "" && this.hasClassName(_id, "Hide");
	},

	do_show: function(_id) {
		if (!_id) { return false; }
		this.select_dom(_id).style.display = "block";
	},
	do_hide: function(_id) {
		if (!_id) { return false; }
		this.select_dom(_id).style.display = "none";
	},

	hasClassName: function(element, className) {
		if (!(element = this.select_dom(element))) return;
		var elementClassName = element.className;
		return (elementClassName.length > 0 && (elementClassName == className ||
			new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
	}
};
var ToggleElementDisplay = function(_elements) {
	if (typeof _elements == "string") {
		var _elements = new Array(_elements);
	}

	for (var i=0; i<_elements.length; i++) {
		if (DisplayController.is_show(_elements[i])) {
			DisplayController.do_hide(_elements[i]);
		}
		else {
			DisplayController.do_show(_elements[i]);
		}
	}
}
var SwitchElementDisplay = function(_shows, _hides) {
	if (!_hides) {
		_hides = "";
	}

	if (typeof _shows == "string") {
		var _shows = new Array(_shows);
	}
	if (typeof _hides == "string") {
		var _hides = new Array(_hides);
	}

	for (var i=0; i<_shows.length; i++) {
		DisplayController.do_show(_shows[i]);
	}
	for (var i=0; i<_hides.length; i++) {
		DisplayController.do_hide(_hides[i]);
	}
}

// User Search popup
var ToggleSeachGroup = function() {
	var id = "search_group";
	if (DisplayController.is_show(id)) {
		DisplayController.do_hide(id);
	}
	else {
		DisplayController.do_show(id);
	}
}

var FileSizeFormatter = {
	parse : function(filesize) {
		var _size = ["", "K", "M", "G", "T"];
		var div = 0;
		var rst = filesize;
		var NUM = 1024;

		while(rst > NUM) {
			div += 1;
			rst = rst / NUM;
		}

		if(rst < 10) {
			rst = rst * 10;
			rst = Math.round(rst);
			rst = rst / 10;
		} else {
			rst = Math.round(rst);
		}

		return rst + _size[div];
	}
};


//
var will_upload = function(me, ele) {
	if (me.checked == true) {
		SwitchElementDisplay("", ele);
	}
	else {
		SwitchElementDisplay(ele);
	}
}

var is_function = function(obj) {
	if (typeof(obj) == "function") {
		return true
	}
	return false;
}
var is_string = function(obj) {
	if (typeof(obj) == "string") {
		return true
	}
	return false;
}
var is_exists = function(obj) {
	if (is_string(obj)) {
		var obj = document.getElementById(obj);
	}
	if (obj) {
		return true;
	}
	return false;
}