/**
 * @requires swfobject.js
 * @requires config.js
 */

// http://la.ma.la/blog/diary_200702152107.htm
Function.toNative = function(obj, method_name){
    return function(){
        var params = [];
        for(var i=0;i<arguments.length;i++) params[i] = "_"+i;
        return Function(
            params.join(','),
            'this["'+method_name+'"]('+params.join(',')+')'
        ).apply(obj, arguments);
    }
}

// 範囲指定出来る+整数なMath.random()
Math.randomInt = function(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + max;
};

// 桁区切りのカンマを追加
Number.prototype.toFigureString = function() {
	var ret = this.toString();
	while(ret != (ret = ret.replace(/^(-?\d+)(\d{3})/, '$1,$2')));

	return ret;
};

/**
 * 0埋め
 * @param {Number} place 0埋めする桁。デフォルトで2
 */
Number.prototype.toFormatString = function(place/*= 2*/) {
	if (!place) place = 2;
	var s = this.toString();
	while (s.length < place)
		s = '0' + s;
	return s;
};

String.prototype.truncate = function(to) {
	return this.length > to ? this.slice(0, to - 3)+'...' : this;
};


var Template = {};

// get from textarea
Template.get = function(element, obj, replacement) {
	return this.apply(element, obj, replacement);
};

Template.apply = function(str, obj, replacement) {
	return str.replace(/#\{(.+?)\}/g, function() {
		try {
			return eval('obj.' + arguments[1]);
		}
		catch (e) {
			return replacement ? replacement : '';
		};
	});
};


/**
 * ExternalInterface用のラッパークラス
 * @requires SWFObject
 */
/**
 * @constructor
 * @param {Object} SWFObject args
 */
function Bridge(args, options) {
	this.id = args.id;
	this.swf = new SWFObject(args.swf, args.id, args.width, args.height, args.version || 9, args.color || '#FFFFFF');
	Bridge.setOption(this.swf, options);

	this.element = null;
	this.obj = null;
}

Bridge.prototype = {
	load: function(element) {
		// console.log(document[this.id]);
		var self = this;

		this.appendTo(element);
//		this.call = $.browser.msie ? window[self.id] : document[self.id];
		// this.call = (function() {
		// 	var obj = $.browser.msie ? window[self.id] : document[self.id];
		// 	console.log('loop');
		// 	if (typeof obj == 'undefined') {
		// 		setTimeout(arguments.callee.caller, 100);
		// 		return;
		// 	}
		// 	self.is_loaded = true;
		// 	return obj;
		// })();

		return this;
	},

	call0: function(f/*, args..*/) {

		f.apply(this, $.inArray(arguments).slice(1));
	},

	call: function(callback) { // FIXME not work..
		var self = this;

		if (this.obj) {
			callback(this.obj);
			return;
		}

		(function() {
			var obj = $.browser.msie ? window[self.id] : document[self.id];
			// console.log(obj);
			if (!obj) {
				// console.log('><')
				setTimeout(arguments.callee.caller, 100);
				return;
			}
			self.obj = obj;
			callback(obj);
		})();
		return this;
	},

	appendTo: function(element) {
		this.element = element;
		this.swf.write(element);
		return this;
	},

	remove: function() {
		$('#' + element).remove();
		return this;
	}
};

Bridge.setOption = function(swf, options) {
	$.each(options, function(method, option) {
		(typeof option == 'object' && option instanceof Array)
			? $.each(option, function(i) { swf[method](i); })
			: $.each(option, function(k, v) { swf[method](k, v); });
	});
};


// var log = function() {
// 	return (!console || !console.log) ? function() {} : console.log;
// };

var parseLocationHash = function(hash/*= location.hash*/) {
	hash = decodeURIComponent(hash || location.hash).replace(/^.*#/, '');
	if (!hash) return;

	var ret = {};
	$.each(hash.split('&'), function(param) {		
		var p = $.map(param.split('='), function(n) { return decodeURIComponent(n); });
		ret[p[0]] = p[1];
	});
	return ret;
};


var Loading = function() {
	if (!$('#status').length)
		$('body').append('<div id="status"/>');
};

Loading.prototype.start = function() {
	this.$div = $('<div class="loading"/>');

	var w = Math.randomInt(10, 33);
	var h = Math.randomInt(5, 15);
	this.$div
		.css({
			zIndex: 1000,
			top   : (50 - h / 2) + '%',
			left  : (50 - w / 2) + '%',
			width : w + '%',
			height: h + '%'
		})
		.appendTo('#status');
};

Loading.prototype.finish = function() {
	this.$div.fadeOut('normal', function() { $(this).remove(); });
};


// http://la.ma.la/misc/js/lazy_writer/
document.lazy_writer = (function(){
	function lazy_writer(url, callback, option){
		var session = {
			script_count  : 0,
			call_count    : 0,
			context       : [],
			stash         : {},
			timer         : null,
			delay         : 0,
			current_script: null
		};
		if(option){
			for(var key in option){
				session[key] = option[key];
			}
		}
		var f = function(script, str){
			session.call_count++;
			if(session.timer){
				clearTimeout(session.timer)
			}
			// run other script -> force write old script
			if(session.current_script && session.current_script != script){
				callback.call(session, session.context.join(""));
				session.context = [];
				session.current_script = script;
				session.script_count++;
			} else if(session.current_script != script){
				session.current_script = script;
				session.script_count++;
			}
			session.context.push(str);
			session.timer = setTimeout(function(){
				callback.call(session, session.context.join(""));
				session.context = [];
			}, session.delay);
		};
		lazy_writer.register(url, f);
	}
	lazy_writer.writers = {};
	lazy_writer.patterns = [];
	lazy_writer.register = function(expr, callback){
		var pair;
		if(typeof expr == 'string'){
			lazy_writer.writers[expr] = callback;
			pair = [function(url){return url.indexOf(expr) != -1}, callback];
		}
		if(typeof expr == 'function'){
			pair = [expr, callback];
		}
		if(expr.constructor == RegExp){
			pair = [function(url){return expr.test(url)}, callback];
		}
		pair && lazy_writer.patterns.push(pair);
	};
	lazy_writer.exists = function(url){
		return lazy_writer.fetch(url) ? true : false;
	};
	lazy_writer.fetch = function(url){
		if(lazy_writer.writers.hasOwnProperty(url)){
			return lazy_writer.writers[url]
		}
		for(var i=0,pair;pair=lazy_writer.patterns[i];i++){
			if(pair[0](url)) return pair[1]
		}
	};
	var original_document_write = document.write;
	document._write = document.write;
	function getCurrentScript(){
		return (function (e) {
			if(e.nodeName.toLowerCase() == 'script') return e;
			return arguments.callee(e.lastChild)
		})(document);
	}
	document.write = function(){
		var current = getCurrentScript();
		var writer;
		if(writer = lazy_writer.fetch(current.src)){
			var args = Array.prototype.slice.call(arguments);
			writer(current, args.join(""));
		} else {
			try{
				// doesn't work in IE and Safari
				original_document_write.apply(document, arguments);
			} catch(e){
				var args = Array.prototype.slice.call(arguments);
				try {
					original_document_write(args.join("")); // for IE
				} catch(e){
					document._write(args.join("")); // for Safari
				}
			}
		}
	};
	return lazy_writer;
})();
