function preInit() {

	mailTo.addContact({
		info: {
			to: "109,-12,117,-9,109,-8,111,-6,108,8,56,59,45,60,54,43,64,33,83,14,107,-10,56,43,68,41",
			subject: "お問い合わせ[www.maildegift.co.jp]"
		}
	});

	openWindow.addType({
		all: { size: [688, 0.8], feat: "all" },
		min: { size: [688, 0.8], feat: "min" },
		none: { size: [688, 0.8], feat: "none" },
		scroll: { size: [688, 0.8], feat: "scroll" },
		resize: { size: [688, 0.8], feat: "resize" }
	});
}

function initPage() {
	smoothScroll.init(/.+[:.].+/);
	openWindow.init();
	setActiveLinkStates();
}

//-- hook onload event
if (window.addEventListener) window.addEventListener("load",initPage,false);
else if (window.attachEvent) window.attachEvent("onload",initPage);
else if (typeof document.readyState != "undefined") {
	function WINDOW_CHECK_LOAD() {
		if (document.readyState == "complete") {
			window.clearInterval(WINDOW_LOAD_TIMER);
			initPage();
			delete WINDOW_CHECK_ONLOAD;
		}
	}
	WINDOW_LOAD_TIMER = window.setInterval("WINDOW_CHECK_LOAD()",0);
}

/*----------------------------------------------------------
| environmental info
+---------------------------------------------------------*/
(function() { //-- get enviromental info (Shitbox or not Shitbox? That is the question!)
	var ua = navigator.userAgent.toLowerCase();
	isIE = (ua.indexOf("opera") < 0 && ua.indexOf("msie") >= 0) ? true : false;
	isMac = (ua.indexOf("mac") >= 0) ? true : false;
})();

/*----------------------------------------------------------
| Object extension (poor man's extensibility)
+---------------------------------------------------------*/
function extendObject(me,my) {
	if (typeof me == "string") me = (window[me]) ? window[me] : (window[me] = {});
	var p = ((me.constructor) ? me.constructor : Object).prototype; //-- get prototype container
	for (var k in my) if (my[k] != p[k]) me[k] = my[k]; //-- we don't take kindly to prototypes here! Read this "if" statement out loud 10 times, fast! ;)
	return me;
}

/*----------------------------------------------------------
| set active link states
+---------------------------------------------------------*/
function setActiveLinkStates() {
	//-- RE -> (protocol|head aliases/root)?(domain)(path)(query|anchor)
	var pathRE = /^(.+:\/+|[.\/]+)?([^\/?#]+)(\/[^?#]*)([?#].*)?$/;
	var loc = location.href.match(pathRE);
//	alert(loc);
	for (var i = 0; i < document.links.length; i++) {
		var a = document.links[i];
		var path = a.href.match(pathRE);
		if (!path || path[2] != loc[2]) continue; //-- no path || different domain
		if (path[3] == "/" && loc[3] != "/") continue; //-- not top page
		if (loc[3].indexOf(path[3]) >= 0) className.add(a,"alink");
	}
}

/*----------------------------------------------------------
| mailTo
+-----------------------------------------------------------
| TODO:
| + add cc,content
| + add a more robust adding "contact.add()" function
| + allow multiple to,cc
+---------------------------------------------------------*/
mailTo = extendObject(function(to) {
	mailTo.send(to);
},{
	contacts: {},

	addContact: function(p) {
		extendObject(this.contacts,p);
	},

	send: function(to) {
		if (!to) for (to in this.contacts) break; //-- get first contact
		to = this.contacts[to];
		if (!to) return;
		var send = "mailto:" + this.resolve(to.to);
		if (to.subject) send += "?subject=" + to.subject;
		location.href = send;
	},

	resolve: function(to) {
		if (!to) return false;
		to = to.split(",").reverse();
		for (var i = 0; i < to.length; i++) {
			to[i] = to[i] * 1;
			if (i < to.length - 1) to[i] += to[i+1] * 1;
			to[i] = String.fromCharCode(to[i]);
		}
		return to.reverse().join("");
	},

	make: function(to) {
		to = to.split("");
		for (var i = 0; i < to.length; i++) {
			to[i] = to[i].charCodeAt(0);
			if (i > 0) to[i] -= to[i-1];
		}
		alert(to);
	}
});

/*----------------------------------------------------------
| smoothScroll v1.0[07.03.14]
+-----------------------------------------------------------
| Syntax:
| smoothScroll([to][,to_y]); Mixed (String|Number|Element)
| e.g.
| smoothScroll();                  => top/left of page (default)
| smoothScroll("non_existent_id"); => top/left of page (default)
| smoothScroll("~");               => top of page (no x scrolling)
| smoothScroll("elem1","elem2");   => scroll to "elem1" left x "elem2" top
| smoothScroll(100,100);           => scroll to 100 x 100
| smoothScroll("100","-100");      => offset by 100 x -100 pixels
| smoothScroll(100,Element);       => scroll to 100 x Element top
+-----------------------------------------------------------
| Special Case Hashes:
| + unknown ID => top/left of page                [e.g. href="#unknown_id"]
| + "."        => top of page (no x scrolling)    [e.g. href="#."]
| + "_"        => bottom of page (no x scrolling) [e.g. href="#_"]
| + ":"        => left of page (no y scrolling)   [e.g. href="#:"]
| + ";"        => right of page (no y scrolling)  [e.g. href="#;"]
+-----------------------------------------------------------
| NOTES:
| + [op] ignores empty hashes [e.g. href="#"] *bitch*, so hashes must have an value [e.g. href="#."]
+-----------------------------------------------------------
| TODO:
| + add down/right decelaration (imposible in [ie])
| + rewrite as Class
+---------------------------------------------------------*/

smoothScroll = extendObject(function() {
	smoothScroll.start(arguments);
},{
		 bias: 6,       //-- scroll bias (for calculating scroll step - deceleration)
	 interval: 30,      //-- scroll interval (ms)
	  minStep: [1,1],   //-- minimum scroll step [x,y] (pixels)
	  maxStep: [50,50], //-- maximum scroll step [x,y] (pixels)
	endOffset: [0,-8],  //-- end scroll position offset [x,y] (pixels)
	cancelBuf: 8,       //-- onscroll cancel buffer (pixels)
	   enable: [1,1],   //-- enable scrolling for [x,y] (true|false)
	marginMIE: [0,0],   //-- [ie:mac] only doesn't recognize body margins (set same value as in CSS or <body> tag attributes) 
	 ignoreRE: /.[:.]./, //-- ignore hashes RegExp - can also be passed on initialization (overrides default)

	init: function(ignoreRE) {
		if (ignoreRE == null) ignoreRE = this.ignoreRE;

		//-- init links
		var docuri = location.href.toString().match(/([^?#]+)(\?[^#]*)?(#.*)?$/);
		for (var i = 0; i < document.links.length; i++) {
			var a = document.links[i];
			var uri = a.href.match(/([^?#]+)(\?[^#]*)?(#.*)?$/);
			if (!(docuri[1] == uri[1] && uri[3])) continue;
			var hash = uri[3].substr(1);
			if (ignoreRE && hash.match(ignoreRE)) continue;
			a.href = "javascript:smoothScroll('" + hash + "')";
		}

		//-- hook onscroll (cancel) event
		if (window.addEventListener) window.addEventListener("scroll",smoothScroll.cancel,true);
		else if (window.attachEvent) window.attachEvent("onscroll",smoothScroll.cancel);
		else window.onscroll = smoothScroll.cancel;

	},

	start: function() {
		var me = smoothScroll;
		if (me.active) return; //-- already started
		me.done = [!me.enable[0], !me.enable[1]];
		me.cPos = me.getCurPos();
		me.ePos = me.getEndPos(arguments[0]);
		me.dir = [
			((me.ePos[0] - me.cPos[0]) > 0) ? 1 : -1,
			((me.ePos[1] - me.cPos[1]) > 0) ? 1 : -1
		];
		me.firstStep = true; //-- no canceling on first step
		me.active = true;
		me.timer = setInterval("smoothScroll.go()",me.interval);
	},

	stop: function() {
		var me = smoothScroll;
		if (!me.active) return; //-- already stopped
		me.cPos = me.ePos = me.oPos = me.dir = null; //-- cleanup
		me.active = false;
		clearInterval(me.timer);
	},

	go: function() {
		if (!smoothScroll.active) return; //-- prevent direct calls

		//-- reference values
		var c = this.cPos;
		var e = this.ePos;
		var done = this.done;

		//-- calc new position
		var s = [0,0];
		for (var i = 0; i < s.length; i++) if (!done[i]) {
			s[i] = Math.round(Math.abs((e[i] - c[i]) / this.bias)); //-- calc step
			s[i] = Math.max(Math.min(s[i], this.maxStep[i]), this.minStep[i]); //-- limit step
			if (s[i] > Math.abs(e[i] - c[i])) s[i] = Math.abs(e[i] - c[i]); //-- final step
			c[i] += s[i] * this.dir[i]; //-- add step
		}

		//-- scroll/check bounds (if there is no change in position, stop scrolling)
		//-- this sucks but there is no difinetive way to check the page scrollable width/height for all browsers (especially shitbox)
		var op = this.getCurPos();
		window.scrollTo(c[0],c[1]);
		var np = this.getCurPos();
		if (!done[0] && op[0] == np[0]) done[0] = true; //-- stop "x" scrolling
		if (!done[1] && op[1] == np[1]) done[1] = true; //-- stop "y" scrolling
		if (done[0] && done[1]) this.stop();
	},

	getCurPos: function() {
		var w = window;
		var b = document.body;
		var d = document.documentElement;
		return [
			w.pageXOffset || b.scrollLeft || (d && d.scrollLeft) || 0,
			w.pageYOffset || b.scrollTop  || (d && d.scrollTop)  || 0
		];
	},

	getEndPos: function(to) {
		var to = [to[0], (to[1]) ? to[1] : to[0]];
		var c = (this.cPos) ? this.cPos : this.getCurPos();
		var eo = this.endOffset;
		var d = document;

		//-- calculate position
		var p = [0,0]; //-- default: top/left of page
		for (var i = 0; i < to.length; i++) {

			//-- resolve "to" position
			var t = to[i];
			if (typeof t == "number") p[i] = t; //-- absolute position
			else if (!isNaN(t)) p[i] = c[i] + (1 * t); //-- offset by pixels
			else if (typeof t == "string") switch(t) {
				case "_": case ".": //-- "y" only scrolling
					if (i == 1) p[i] = (t == "_") ? this.getPgSize()[1] : 0; //-- bottom|top
					else this.done[0] = true; //-- disable "x" scrolling
					break;
				case ":": case ";": //-- "x" only scrolling
					if (i == 0) p[i] = (t == ";") ? this.getPgSize()[0] : 0; //-- left|right
					else this.done[1] = true; //-- disable "y" scrolling
					break;
				default: t = d.getElementById(t); //-- scroll to element
			}

			//-- if to element, get position
			if (t && t.tagName) do {
				p[i] += (i == 0) ? t.offsetLeft : t.offsetTop;
			} while (t = t.offsetParent);

			//-- adjust position
			if (isIE && isMac) p[i] += this.marginMIE[i]; //-- [ie:mac] body margin adjustment
			p[i] = Math.max(p[i] + this.endOffset[i],0);  //-- add scroll end offset
		}

		return p;
	},

	getPgSize: function() {
		var b = document.body;
		var d = document.documentElement;
		return [
			(d && d.scrollWidth)  ? d.scrollWidth  : (b.scrollWidth  > b.offsetWidth)  ? b.scrollWidth  : b.offsetWidth + b.offsetLeft,
			(d && d.scrollHeight) ? d.scrollHeight : (b.scrollHeight > b.offsetHeight) ? b.scrollHeight : b.offsetHeight + b.offsetTop
		];
	},

	cancel: function() {
		var me = smoothScroll;
		if (!me.active) return;
		if (me.firstStep) return me.firstStep = false;
		var c = me.cPos;
		var s = me.getCurPos();
		var b = me.cancelBuf;
		for (var i = 0; i < s.length; i++)
			if (!me.done[i] && Math.abs(s[i] - c[i]) > b) return me.done = [true,true];
	}

});


/*----------------------------------------------------------
| getByClass
+---------------------------------------------------------*/
function getByClass(re,tag,branch,maxMatches) {
//-- RETURNS: (maxMatches === true) ? single element : array of elements
	if (!re) re = /.*/;
	else if (typeof re == "string") re = new RegExp("\\b(" + re + ")\\b");
	if (!branch) branch = document;
	else if (typeof branch == "string") branch = document.getElementById(branch);
	if (!tag) tag = "*";
	var out = [];
	var tags = branch.getElementsByTagName(tag);
	for (var i = 0; i < tags.length; i++) {
		var t = tags[i];
		if (t.className.match(re)) {
			if (maxMatches === true) return t;
			else {
				out[out.length] = t;
				if (maxMatches && out.length + 1 > maxMatches) return out;
			}
		}
	}
	return (out.length > 0) ? out : (maxMatches === true) ? null : [];
}

/*----------------------------------------------------------
| Class Manager
+---------------------------------------------------------*/
className = {
	add: function(obj,cls) {
		return this.set(obj,cls,true);
	},
	remove: function(obj,cls) {
		return this.set(obj,cls,false);
	},
	toggle: function(obj,cls) {
		return this.set(obj,cls,(this.has(obj,cls)) ? false : true,true);
	},
	replace: function(obj,removeCls,addCls,alwaysAdd) {
		var removed = this.set(obj,removeCls,false);
		if (removed || alwaysAdd) this.set(obj,addCls,true);
		return removed;
	},
	addIfHas: function(obj,testCls,ifCls,elseCls) {
		return this.set(obj,(this.has(obj,testCls)) ? ifCls : elseCls,true);
	},
	removeIfHas: function(obj,testCls,ifCls,elseCls) {
		return this.set(obj,(this.has(obj,testCls)) ? ifCls : elseCls,false);
	},
	toggleIfHas: function(obj,testCls,ifCls,elseCls) {
		return this.toggle(obj,(this.has(obj,testCls)) ? ifCls : elseCls);
	},
	has: function(obj,cls) {
		return (cls) ? ((obj.className.match(this.toRE(cls))) ? true : false) : false;
	},
	set: function(obj,cls,setit,verified) {
		if (!cls) return false;
		if ((setit || typeof setit == "undefined")) {
			if (verified || !this.has(obj,cls)) {
				obj.className += (obj.className) ? " " + cls : cls;
				return true;
			}
		} else if (verified || this.has(obj,cls)) {
			obj.className = obj.className.replace(this.toRE(cls),"");
			return true;
		}
		return false;
	},
	toRE: function(cls) {
		return (typeof cls == "object" && cls.exec) ? cls : new RegExp("\\s*(" + cls + ")\\b");
	}
}

/*----------------------------------------------------------
| window control
+---------------------------------------------------------*/
openWindow = extendObject(function(id,url) {
	openWindow.open(id,url);
},{

	features: {
		none: "scrollbars=0,resizable=0",
		scroll: "scrollbars=1,resizable=0",
		resize: "scrollbars=0,resizable=1",
		min: "scrollbars,resizable=1",
		all: "location,menubar,toolbar,status,scrollbars,resizable=1"
	},

	types: {},

	addType: function(p) {
		extendObject(this.types,p);
	},

	init: function(branch) {
	//-- retry this with new $tasks (it might work)
	// !!! unfortunatly form "onsubmit" events cannot be set via "tasks.add()" !!!
	// FIX: use "submitForm()" or place openWindow() directly in <form> tag.
		var a = (branch) ? branch.getElementsByTagName("a") : document.links;
		for (var i = 0; i < a.length; i++)
			if (a[i].target.match(/^win_/)) a[i].onclick = new Function("openWindow('" + a[i].target + "')");
	},

	open: function(id,url) {
		if (url == null) { url = ""; }
		id = (id) ? id.replace(/^win_/,"") : "new";
		var p = this.types[id];

		var w = 0;
		var h = 0;
		if (p && p.size) {
			if (p.size[0]) w = (p.size[0] > 1) ? p.size[0] : Math.round(screen.width * p.size[0]);
			if (p.size[1]) h = (p.size[1] > 1) ? p.size[1] : Math.round(screen.height * p.size[1]);
		}

		var f = (p && p.feat) ? p.feat : "";
		if (f && this.features[p.feat]) f = this.features[p.feat];
		if (w > 0 && h > 0) {
			var x = (screen.width - w) / 2;
			var y = (screen.height - h) / 2;
			if (isIE) { y -= 32; }
			f += ((f) ? "," : "") + "height=" + h + ",width=" + w + ",top=" + y + ",left=" + x;
		}

		id = "win_" + id;
		var w = (window[id]) ? window[id] : window.open(url,id,f);
		w.focus();
	}

});

preInit();
