
debug = !(/(?:www\d?\.)?beyes\.jp/.test(location.host));

if (typeof console == 'undefined') {
	console = {};
	console.log = function() {
		try {
			var res = [];
			for (var i = 0, length = arguments.length; i < length; i++)
				res.push(arguments[i].toString());
			if ($.browser.opera)
				opera.postError(res.join(', '));
		}
		catch (e) {}
	};
}
log = function() {
	debug ?
		console.log.apply(console.log, arguments) :
		null;
};


// error in jQuery 1.4
// Array.prototype.clone = function() {
// 	return this.concat();
// };

Number.prototype.toFigureString = function() {
	var str = this.toString();
	while (str != (str = str.replace(/^(-?\d+)(\d{3})/, '$1,$2')));
	return str;
};

Number.prototype.toFormatString = function(place) {
	place = place || 2;
	var str = this.toString();
	while (str.length < place) str = '0'+str;
	return str;
};

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

String.prototype.stripTag = function() {
	return this.toString().replace(/<[^>]+>/g, '');
};

String.prototype.escapeTag = function() {
	return this.toString()
		.replace(/&/g, '&amp;')
		.replace(/"/g, '&quot;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;');
};

String.prototype.capitalize = function() {
	return this.toString().replace(/\b[a-z]/g, function(w) {
		return w.toUpperCase();
	});
};


if ($.browser.msie) document.execCommand('BackgroundImageCache', false, true);


storage = function(key, value) {
	if (!window.sessionStorage) return false;
	return value ?
		(sessionStorage[key] = JSON.stringify(value)) :
		(sessionStorage[key] ? eval('('+sessionStorage[key]+')') : null);
};

applyTemplate = (function() {
	var markup = /#\{([^|}]+)(?:\|(.*?)\|)?\}/g;
	return function(t, o, escape) {
		return (!t || !o) ?
			t :
			t.replace(markup, function(_, prop, alt) {
				alt = alt || '';
				prop = (o[prop] || alt);
				return escape ? prop.escapeTag() : prop;
			});
	};
})();

parseQuery = function(queries) {
	var ret = null;
	var m = /#(.+)/.exec(queries || location.href); // location.hashでは勝手ににデコードされてしまう
	if (m)
		queries = m[1];
	else
		return ret;

	var query = queries.split('&');
	for (var i = 0, length = query.length; i < length; ++i) {
		var q = query[i];
		if (!q) continue;
		var p = $.map(q.split('='), function(n) {
			return decodeURIComponent(n);
		});
		if (!p[1]) continue;
		ret = ret || {};
		ret[p[0]] = Number(p[1]) || p[1];
	}
	return ret;
};

hash = {
	keys: function() {
		var ret = [];
		for (var i = 0, length = arguments.length; i < length; ++i) {
			var o = arguments[i];
			if (typeof o == 'object')
				for (var k in o) ret.push(k);
			else
				ret.push(o);
		}
		return ret;
	},

	values: function() {
		var ret = [];

		for (var i = 0, length = arguments.length; i < length; ++i) {
			var o = arguments[i];
			if (typeof o == 'object')
				for (var k in o) ret.push(o[k]);
			else
				ret.push(o);
		}
		return ret;
	}
};
getKey = hash.keys;
getValue = hash.values;

store = (function() {
	var store = [];

	return {
		list: function() {
			var ret = {};
			var length = 0;
			$.each(store, function(k, v) {
				if (v === undefined) return;
				ret[k] = v;
				++length;
			});
			ret.length = length;
			return ret;
		},

		save: function(value) {
			var id = store.length;
			store.push(value);
			return id;
		},

		load: function(id) {
			return store[id] || null;
		},

		restore: function(id) {
			var ret = this.load(id);
			this.clear(id);
			return ret;
		},

		clear: function(id) {
			if (id !== undefined && store[id])
				delete store[id];
			else
				store = [];
			return store;
		}
	};
})();


Class = function(prototype, base) {
	var c = prototype.initialize || (
		base ?
			function() { return base.apply(this, arguments); } :
			function() {}
		);
	c.prototype = prototype;
	c.prototype.constractor = c;
	if (base) {
		c.SUPER = base;
		c.prototype.SUPER = base.prototype;
		Class.extend(base, c);
		Class.extend(base.prototype, c.prototype);
	}
	return c;
};
Class.extend = function(base, self) {
	for (var k in base)
		if (typeof self[k] == 'undefined' && k != 'initialize')
			self[k] = base[k];
	return self;
};


$.extend($.browser, {
	msie6: $.browser.msie && $.browser.version < 7
});

$.override = function(target, copy) {
	$.each(copy, function (k, v) {
		if (v === null)
			delete target[k];
		else if (typeof v == 'object') {
			target[k] = target[k] || ($.isArray(v) ? [] : {});
			var t = target;
			var c = copy;
			target = target[k];
			copy = copy[k];
			$.each(v, arguments.callee);
			target = t;
			copy = c;
		}
		else
			target[k] = v;
	});
	return target;
};

new function() {
	var template = [
		'<div id="imagebox">',
		'<div class="grayback"/>',
		'<div class="main">',
		'<p class="image"><a href="#" title="Close"/></p>',
		'<p class="close"><a href="#" title="Close">Close</a></p>',
		'</div>',
		'</div>'
	].join('');
	var shown = false;
	var container = null;
	var scrollTop = null;

	$.fn.imagebox = function() {
		return this.each(function() {
			var src = this.href;
			if (!src) return;

			$(this).click(function() {
				scrollTop = $(window).scrollTop();

				var img = $('<img src="'+src+'" alt=""/>');
				img.load(function() {
					if (shown && container)
						container
							.show()
							.find('p.image > a').html(img);
					else {
						var css = { opacity: 0.5 };
						if ($.browser.msie6)
							css.height = Math.max($(window).height(), $().height(), $('body').height());

						container = $(template)
							.find('div.grayback').css(css).end()
							.appendTo('body')
							.find('p.image > a').html(img).end();
						container.find('a').click(function() {
							container.hide();
							$(window).scrollTop(scrollTop);
							shown = false;
							return false;
						});
					}
					shown = true;

					var main = $('div.main', container);
					var w = img[0].width + 30;
					main.css({
						left : $(window).width() / 2 - w / 2,
						width: w
					});
					if (scrollTop > 0)
						setTimeout(function() {
							$(window).scrollTop(0);
						}, 0);
				});

				return false;
			});
		});
	};
};

$.fn.fl = function(o) {
	if (!this.length) return this;

	if (!o) {
		var id = this.attr('id');
		return $.browser.msie ? window[id] : document[id];
	}

	var v = '9.0.47';
	o = $.extend({
		version         : v,
		params          : { wmode: 'transparent' },
		expressInstaller: '/swf/src/expressInstall.swf'
	}, o);

	if (
		!swfobject.hasFlashPlayerVersion('6.0.65') ||
		!swfobject.hasFlashPlayerVersion(v) && o.expressInstaller == 'html'
	)
		return o.expressInstaller ?
			this.html([
				'<p class="noteSwf01">',
				'<a href="/" class="logoBeyes"><img src="/img/common/logo_beyes_01.png" alt="BEYES" width="118" height="21"/></a>',
				'<span>このコンテンツをご覧いただくためには、<br />最新のAdobe Flash Player（無償）が必要です。',
				'<a href="http://www.adobe.com/go/getflashplayer_jp" title="Adobe Flash Playerダウンロードページへ">Adobe Flash Playerダウンロードページへ</a>',
				'</span>',
				'</p>'
			].join('')) :
			this;

	swfobject.embedSWF(
		o.src,
		this[0].id,
		o.width,
		o.height,
		o.version,
		o.expressInstaller,
		o.flashvars,
		o.params,
		o.attrs
	);
	return this;
};

$.fn.roll = function roll(o) {
	o = o || '_o';
	return this.each(function() {
		var self = $(this);
		var src = this.src;
		if (!src) {
			var target = $('img, input[type="button"]', this);
			if (target.length) roll.call(target, o);
			return;
		}

		var out  = src;
		var over = src.replace(/(\.[^.]+$)/, o+'$1');
		$('<img src="'+over+'"/>');
		self.hover(
			function() {
				if (self.data('selected')) return;
				this.src = over;
			},
			function() {
				if (self.data('selected')) return;
				this.src = out;
			}
		);
	});
};

$.fn.external = function() {
	return this.each(function() { this.target = '_blank'; });
};

$.fn.tall = function() {
	var tall = 0;
	return this
		.each(function() {
			tall = Math.max(tall, $(this).height());
		})
		.height(tall);
};

$.fn.pulldown = function(list, manipulate, current, callback) {
	if (!list) return this;
	var self = this;

	current    = (typeof current == 'string') ? current : list[current || 0];
	manipulate = (typeof manipulate == 'function') ?
		manipulate :
		function() {
			var klass = (typeof manipulate == 'string') ? manipulate : 'selectbox01';
			$(this).addClass(klass);
		};

	return this.each(function() {
		var container = $([
			'<ul class="select">',
			'<li class="current"><a/></li>',
			'<li class="list">',
			'<ul/>',
			'</li>',
			'<li class="btnSelect"><a href="#"/></li>',
			'</ul>'
		].join(''));
		var li = $('.list', container);
		container
			.appendTo(this)
			.each(manipulate)
			.hover(
				function() { li.slideDown(100, 'easeOutCubic'); },
				function() { li.slideUp(100, 'easeOutCubic'); }
			)
			.find('.current a').text(current).end()
			.find('.btnSelect a').click(function() { return false; });

		var ul = $('.list ul', container);
		$.each(list, function(_, text) {
			$('<li><a href="#">'+text+'</a></li>')
				.appendTo(ul)
				.find('a').click(function() {
					$('.current a', container).text(text);
					var i = $.inArray($(this).text(), list);
					if (callback) callback.call(this, i);

					li.hide();
					return false;
				});
		});
	});
};

$.fn.hoverClass = function() {
	if (!$.browser.msie6) return this;

	var self = this;
	return this.hover(
		function() { self.addClass('hover'); },
		function() { self.removeClass('hover'); }
	);
};


config = {
	type: null,
	logging: true,

	types: ['men', 'women', 'unisex', 'zakka'],

	genre: ['すべて', 'アメリカン カジュアル', 'ヨーロピアン カジュアル', 'ドレス', 'ミクスチャー', 'カジュアル', 'バッグ＆シューズ＆アザーズ'],

	genres: ['アメリカン カジュアル', 'ヨーロピアン カジュアル', 'ドレス'],
	limits: [18, 30, 60, 90],
	zakkaCategories: {
		'電気製品・時計・証明'        : ['電化製品', '時計', '照明'],
		'キッチン・テーブルウェア'      : ['調理器具', '食器・カトラリー'],
		'バス・トイレタリー・ハウスキーピング': ['バス・トイレ用品', 'ハウスキーピング'],
		'インテリア雑貨'           : [],
		'家具・収納'             : [],
		'ラグ・クッション・ファブリック'   : ['ファブリック雑貨', 'キッチン関連'],
		'寝具・枕'              : [],
		'文具・玩具'             : ['文具', '玩具'],
		'ヘルス・ビューティー'        : ['健康グッズ', 'コスメ'],
		'バッグ・靴･傘'           : ['バッグ', '靴', '傘'],
		'服飾雑貨･アクセサリー'       : ['服飾雑貨', 'アクセサリー'],
		'ウェア'               : ['シャツ', 'カットソー', 'ニット', 'ワンピース', 'ジャケット・コート', 'インナー・ホームウェア', 'パンツ・スカート']
	},
	menPopularBrand: {
		'マッキントッシュ'    : 3950,
		'エンジニアド・ガーメンツ': 6196,
		'インコテックス'     : 6024,
		'リングヂャケット'    : 7130,
		'ダニエル&ボブ'     : 5276,
		'オロビアンコ'      : 5320,
		'スピングルムーヴ'    : 6111,
		'SKAGEN'      : 5957
	},
	men_category: {
		'TOPS'       : ['コート', 'アウター', 'ジャケット', 'スーツ'],
		'INNER'      : ['シャツ', 'カットソー', 'ニット', 'アンダーウェア'],
		'BOTTOM'     : ['デニム', 'トラウザース', 'ショーツ'],
		'BAG'        : ['ビジネスバッグ', 'カジュアルバッグ'],
		'SHOES'      : ['ドレスシューズ', 'カジュアルシューズ'],
		'ACCESSORIES': ['ネクタイ', 'ベルト', '服飾雑貨', '革小物'],
		'INTERIOR'   : ['デスク周り&ステーショナリー', 'リビング、キッチン&テーブルウェア'],
		'HOBBY'      : ['腕時計', '趣味雑貨', 'トーイ', 'Other']
	}
};


if (typeof stash == 'undefined') stash = {};
// stash.uid = new Date().getTime();
stash.title = document.title;
stash.data = storage('data') || {};
// stash.requested = (location.pathname != '/');

data = {};


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


data.types = ['men', 'women', 'unisex', 'zakka'];
BEYES.type = (function() {
	var type = null;

	return function(id) {
		var ret = null;
		if (typeof id == 'string')
			ret = $.inArray(id || BEYES.type(), data.types) + 1 || null;
		else if (typeof id == 'number')
			ret = data.types[id - 1] || null;
		else {
			var b = $('body');
			type = type ||
			b.hasClass('beyesMen') ? 'men' :
			b.hasClass('beyesWom') ? 'women' :
			b.hasClass('beyesZak') ? 'zakka' :
			null;
			ret = config.type || type;
		}
		return ret;
	};
})();

data.genres = [
	['すべて'],
	['アメリカン カジュアル', 'Ame'],
	['ヨーロピアン カジュアル', 'Eur'],
	['ドレス', 'Dre'],
	['ミクスチャー', 'Mix'],
	['カジュアル', 'Cas'],
	['バッグ＆シューズ＆アザーズ', 'Bag']
];
BEYES.genre = function(s) {
	var n = s, ret = null;
	var genres = data.genres;
	if (typeof s == 'string')
		for (var i = 0, length = genres.length; i < length; i++) {
			var genre = genres[i];
			if (genre[0] == s || genre[1] == s) {
				n = i;
				break;
			}
		}

	ret = genres[n] || null;
	if (ret) ret = {
		id  : n,
		name: ret[0],
		abbr: ret[1]
	};
	return ret;
};

data.brands = {
	men  : [
		['マッキントッシュ', 3950],
		['エンジニアド・ガーメンツ', 6196],
		['インコテックス', 6024],
		['リングヂャケット', 7130],
		['ダニエル&ボブ', 5276],
		['オロビアンコ', 5320],
		['スピングルムーヴ', 6111],
		['SKAGEN', 5957]
	],
	women: [],
	zakka: []
};
BEYES.brand = function(id, type) {
	var ret = null;

	var brand = data.brands[type];
	var ii = (typeof id == 'string') ? 0 : 1;
	for (var i = 0, length = brand.length; i < length; i++) {
		var b = brand[i];
		if (b[ii] != id) continue;
		ret = {
			name: b[0],
			id  : b[1]
		};
		break;
	}

	return ret;
};

data.categories = {
	men  : [
		['TOPS', ['コート', 'アウター', 'ジャケット', 'スーツ']],
		['INNER', ['シャツ', 'カットソー', 'ニット', 'アンダーウェア']],
		['BOTTOM', ['デニム', 'トラウザース', 'ショーツ']],
		['BAG', ['ビジネスバッグ', 'カジュアルバッグ']],
		['SHOES', ['ドレスシューズ', 'カジュアルシューズ']],
		['ACCESSORIES', ['ネクタイ', 'ベルト', '服飾雑貨', '革小物']],
		['INTERIOR', ['デスク周り&ステーショナリー', 'リビング、キッチン&テーブルウェア']],
		['HOBBY', ['腕時計', '趣味雑貨', 'トーイ', 'Other']]
	],
	women: [
		['アウター', ['コート', 'ジャケット']],
		['トップス', ['カットソー、Tシャツ', 'ニット、カーディガン', 'シャツ、ブラウス']],
		['ボトムス', ['スカート', 'パンツ']],
		['ワンピース', ['ワンピース']],
		['バッグ', ['バッグ', '財布、革小物']],
		['シューズ', ['シューズ', 'サンダル、ミュール', 'スニーカー']],
		['アクセサリー', ['アクセサリー', '腕時計']],
		['服飾雑貨', ['スカーフ・マフラー', 'ベルト', '帽子', 'その他のファッション雑貨']],
		['趣味雑貨', ['ステーショナリー', 'その他の趣味雑貨']]
	],
	zakka: [
		['電気製品・時計・証明', ['電化製品', '時計', '照明']],
		['キッチン・テーブルウェア', ['調理器具', '食器・カトラリー']],
		['バス・トイレタリー・ハウスキーピング', ['バス・トイレ用品', 'ハウスキーピング']],
		['インテリア雑貨', []],
		['家具・収納', []],
		['ラグ・クッション・ファブリック', ['ファブリック雑貨', 'キッチン関連']],
		['寝具・枕', []],
		['文具・玩具', ['文具', '玩具']],
		['ヘルス・ビューティー', ['健康グッズ', 'コスメ']],
		['バッグ・靴･傘', ['バッグ', '靴', '傘']],
		['服飾雑貨･アクセサリー', ['服飾雑貨', 'アクセサリー']],
		['ウェア', ['シャツ', 'カットソー', 'ニット', 'ワンピース', 'ジャケット・コート', 'インナー・ホームウェア', 'パンツ・スカート']]
	]
};
BEYES.category = function(id, type) {
	type = type || BEYES.type();
	var ret = null;

	var category = data.categories[type];
	if (typeof id == 'string')
		for (var i = 1, length = category.length; i < length; i++)
			if (category[i - 1][0] == id) { id = i; break; }

	var c = category[id - 1];
	if (c) ret = {
		index: id,
		name : c[0],
		sub  : c[1]
	};

	return ret;
};


// TODO remove
BEYES.getType = function(id) {
	if (!id || typeof id != 'number')
		id = BEYES.getTypeId(id);
	var types = config.types.concat();
	types[2] = (config.type == 'women') ? 'women' : 'men';
	return types[id - 1];
};

// TODO remove
BEYES.getTypeId = function(type) {
	return $.inArray(type || config.type, config.types) + 1 || null;
};

// TODO remove
BEYES.setType = function() {
	config.type =
		$('body').hasClass('beyesMen') ? 'men' :
		$('body').hasClass('beyesWom') ? 'women' :
		$('body').hasClass('beyesZak') ? 'zakka' :
		undefined;
};

BEYES.imagePath = function(type) {
	return '/img/'+BEYES.type(type).slice(0, 3);
};


BEYES.parameter = (function() {
	var parameter_key = function() {
		var type = BEYES.type().capitalize();
		return {
			parameter: ['category', 'subcategory', 'brand', 'genre', 'span', 'limit', 'offset'],
			queries  : [type+'Category', type+'SubCategory', 'BrandId', 'GenreId', 'span', 'limit', 'offset']
		};
	};
	var criteria_rules = [
		'IsNull', 'IsNotNull',
		'Equal', 'NotEqual',
		'GreaterThan', 'LessThan',
		'GreaterEqual', 'LessEqual',
		'Like', 'NotLike',
		'In', 'NotIn'
	];

	return {
		get: function(params) {
			params = params || parseQuery() || {};

			var keys = parameter_key();
			var queries = {
				criteria: {
					condition: {}
				}
			};
			for (var param in params) {
				var v = params[param];
				switch (param) {
					case 'offset':
					case 'limit':
						queries.criteria[param] = v;
						break;
					case 'span':
						queries[param] = v;
						break;
					default:
						var n = $.inArray(param, keys.parameter);
						if (n != -1)
							queries.criteria.condition[keys.queries[n]] = v;
				}
			}
			return queries;
		},

		make: function(queries) {
			if (!queries) return null;

			var keys = parameter_key();
			var parameter = {};
			(function scan(queries) {
				for (var query in queries) {
					var v = queries[query];
					if (v === null) continue;

					if (typeof v == 'object')
						scan(v);
					else {
						var n = $.inArray(query, keys.queries);
						if (n != -1)
							parameter[keys.parameter[n]] = v;
					}
				}
			})(queries);

			return parameter;
		},

		update: function(queries) {
			if (!queries) return false;

			var parameter = $.param(BEYES.parameter.make(queries));
			location.hash = parameter;
			return true;
		},

		clean: function() {} // TODO check parameter on input, output
	};
})();


BEYES.Unit = function() {
	var options = arguments.length > 1 ?
		{
			container: arguments[0],
			id       : arguments[1]
		} :
		arguments[0];
	this.o = $.extend({
		container: null,
		id       : null,
		item     : null,
		count    : null,
		column   : null
	}, options);
	this.element = null;
};
BEYES.Unit.prototype = {
	request: function() {
		var o = this.o;
		var id = o.id;
		new BEYES.UnitList({
			container: $(o.container),
			queries  : {
				criteria : {
					condition: {
						Id        : { In: $.isArray(id) ? id : [id] },
						GenderType: BEYES.type()
					}
				},
				page_type: 5
			}
		}).show();
	},

	show: function() {
		var o = this.o;
		var item = o.item;
		if (!item && o.id) return this.request(); // TODO bad idea. object's reference will be lost

		// called by synchronous
		var id = o.id = item.id;
		if (!stash.data[id]) stash.data[id] = item;

		var Unit = BEYES.Unit[BEYES.type(item.gender_type).capitalize()];
		if (!Unit) return;
		new Unit(o).show();
	}
};


BEYES.Unit.Men = BEYES.Unit.Unisex = function(o) {
	this.o = o;
	this.template = [
		'<div class="unit01 unitMen01"#{_unit_style}>',
		'<div class="details">',
		'<h3 class="name">#{name}</h3>',
		'<p class="thumb"><a href="#{_permalink}"><img src="#{product_img}" alt="#{name}" width="130" height="130"#{_thumb_style}/></a></p>',
		'<dl class="info01">',
		'<dt class="price"/><dd class="price#{_price_class}">#{_sale_text}¥#{_price} (税込)</dd><!--#{_sale_percent}-->',
		'<dt class="brand"/><dd class="brand">#{brand_name}</dd>',
		'</dl>',
		'<ul class="info02">',
		'<li class="copy">#{comment}</li>',
		'<li class="genre#{_genre} #{genre_name}">#{genre_name}</li>',
		'</ul>',
		'#{_state}',
		'#{_sold_out}',
		'</div>',
		'<ul class="utility#{_disable_class}">',
		'<li class="variation"><a href="#" onclick="return BEYES.Unit.Unisex.variation.call(this, #{id})"/></li>',
		'<li class="cart">#{_cart_button}</li>',
		'</ul>',
		'</div>'
	].join('');
};

BEYES.Unit.Men.variation = (function() {
	var item_template = [
		'<div class="item"#{_item_style}>',
		'<p class="thumb"><img src="#{color_img}" alt="" width="65" height="65"/></p>',
		'#{_size}',
		'</div>'
	].join('');
	var variation_template = [
		'<div class="variation" style="display:none">',
		'<div class="variation-play">',
		'#{list}',
		'</div>',
		'</div>'
	].join('');

	return function(id) {
		var unit = $(this).parents('.unit01')[0];
		var details = $('.details', unit);
		var variation_button = $('.utility li:eq(0)', unit);
		var variation = $('> .variation', unit);
		var item = stash.data[id];

		if ($(':visible', variation).length) {
			variation.hide();
			variation_button[0].className = 'variation';
			details.fadeIn();
			return false;
		}

		details.hide();
		variation_button[0].className = 'variationOpen';
		if (variation.length)
			variation.fadeIn();
		else {
			var list = [];
			for (var i = 0, l = Math.max(4, item.stocks.length); i < l; i++) {
				var stock = item.stocks[i] || { color_img: '/img/item/color/c_noitem.gif' };
				stock._item_style = (i + 1 == l) ? ' style="margin-right:0"' : '';
				if (stock.sizes) {
					var _size = [];
					for (var ii = 0, ll = stock.sizes.length; ii < ll; ii++) {
						var size = stock.sizes[ii];
						_size.push('<li><span>'+size.size_name+'</span>'+size.stock+'</li>');
					}
					stock._size = '<ul class="size">'+_size.join('')+'</ul>';
				}
				list.push(applyTemplate(item_template, stock));
			}
			list = { list: list.join('') };
			var variation = $(applyTemplate(variation_template, list))
				.appendTo(unit)
				.fadeIn();

			var width = 66 * l - 1;
			var variation_play = $('.variation-play', variation)
				.width(width);
			var height = 0;
			$('.item', variation).each(function() {
				height = Math.max(height, $(this).height(), 142);
			});
			if ($.browser.msie6)
				variation.height(height);
			var scrolling = false;
			variation.mousemove(function(e) {
				if (scrolling) return;

				var offset = $(this).offset();
				var x = e.pageX - offset.left;
				var y = e.pageY - offset.top;
				var left = (x < 75), right = (x > 230), top = (y < 50), bottom = (y > 112);
				var options = {
					duration: 'slow',
					easing  : 'easeOutCubic',
					complete: function() { scrolling = false; }
				};

				if (left || right) {
					var margin = Math.round(parseFloat(variation_play.css('margin-left')));
					var motion = 150;
					if (left) {
						var limit = 0;
						var move = margin + motion;
						if (margin != limit) {
							scrolling = true;
							move = Math.min(move, limit);
							variation_play.animate({ marginLeft: move }, options);
						}
					}
					else if (right) {
						var limit = width * -1 + 263;
						var move  = margin - motion;
						if (margin != limit) {
							scrolling = true;
							move = Math.max(move, limit);
							variation_play.animate({ marginLeft: move }, options);
						}
					}
				}
				if (top || bottom) {
					var margin = Math.round(parseFloat(variation_play.css('margin-top')));
					var motion = 50;
					if (top) {
						var limit = 0;
						var move  = margin + motion;
						if (margin != limit) {
							scrolling = true;
							move = Math.min(move, limit);
							variation_play.animate({ marginTop: move }, options);
						}
					}
					else if (bottom) {
						var limit = height * -1 + 142;
						var move  = margin - motion;
						if (margin != limit) {
							scrolling = true;
							move = Math.max(move, limit);
							variation_play.animate({ marginTop: move }, options);
						}
					}
				}
			});
		}
		return false;
	};
})();

BEYES.Unit.Men.addToCart = function(id) {
	var item = stash.data[id];
	if (!item) return false;
	BEYES.QuickCart.add(item);
	$(this).mouseleave();
	return false;
};

BEYES.Unit.Men.prototype = {
	_item: function() {
		var o = this.o;
		var item = o.item;
		item._disable = (item.sold_out_flag || item.coming_soon_flag || item.status == 5);
		var type = BEYES.type(item.gender_type);
		item._permalink = '/'+(type == 'unisex' ? 'men' : type)+'/item/'+item.id;
		item._unit_style = (o.count != null && (o.count + 1) % (o.column || 3) == 0) ?
			' style="margin-right:0"' :
			'';
		item._state = (
			item.coming_soon_flag ? '<div class="comingSoon">Coming Soon</div>' :
			item.new_flag ? '<div class="new">New</div>' :
			''
		);
		item._genre = BEYES.genre(item.genre_id || 0).abbr;
		item._cart_button = item._disable ?
			'<span/>' :
			'<a href="#" onclick="return BEYES.Unit.Unisex.addToCart.call(this, '+item.id+')"/>';
		item._disable_class = item._disable ? ' disable' : '';
		if (item.sold_out_flag) {
			item._sold_out = '<div class="soldOut">Sold Out</div>';
			item._thumb_style = $.support.opacity ?
				' style="opacity:0.25"' :
			    ' style="filter:alpha(opacity=25)"';
		}
		if (item.sale_flag) {
			item._price_class = ' saleprice';
			item._sale_text = 'SALE<br/>';
			item._price = item.sale_selling_price.toFigureString();
			item._sale_percent = '<dd class="price salepercent">['+item.sale_rate+' off]</dd>';
		}
		else
			item._price = item.selling_price.toFigureString();
	},

	show: function() {
		var self = this;
		var o = this.o;
		if (!o) return;

		var item = o.item;
		this._item();

		var unit = $(applyTemplate(this.template, item))
			.appendTo(o.container)
			.hoverClass();

		var cart = $('.cart', unit)[0];
		$('a', cart).hover(
			function() { cart.className = 'cartOpen'; },
			function() { cart.className = 'cart'; }
		);
	}
};


BEYES.Unit.Women = function(o) {
	this.o = o;
	this.template = [
		'<div class="unit01 unitWom01"#{_unit_style}>',
		'<div class="details">',
		'<h3 class="name">#{name}</h3>',
		'<p class="thumb"><a href="#{_permalink}"><img src="#{product_img}" alt="#{name}" width="130" height="130"#{_thumb_style}/></a></p>',
		'<dl class="info01">',
		'<dt class="price"/><dd class="price#{_price_class}">#{_sale_text}¥#{_price} (税込)</dd><!--#{_sale_percent}-->',
		'<dt class="brand"/><dd class="brand">#{brand_name}</dd>',
		'</dl>',
		'<ul class="info02">',
		'<li class="copy">#{comment}</li>',
		'</ul>',
		'#{_state}',
		'#{_sold_out}',
		'</div>',
		'<ul class="utility#{_disable_class}">',
		'<li class="variation"><a href="#" onclick="return BEYES.Unit.Unisex.variation.call(this, #{id})"/></li>',
		'<li class="cart">#{_cart_button}</li>',
		'</ul>',
		'</div>'
	].join('');
};
BEYES.Unit.Women.prototype = new BEYES.Unit.Men;


BEYES.Unit.Zakka = function(o) {
	this.o = o;
	this.template = [
		'<div class="unitZak01 unitZakType#{_unit_type}"#{_unit_style}>',
		'<h3 class="name">',
		'<a href="#{_permalink}"><img src="#{product_img}" alt="#{name}" width="90" height="90"/></a>',
		'</h3>',
		'<p class="text">#{comment}</p>',
		'#{_state}',
		'</div>'
	].join('');
	this.tooltip_template = [
		'<div class="tooltipZak01 tooltipZakType#{_unit_type}">',
		'<p class="name">#{name}</p>',
		'<dl class="info01">',
		'<dt class="price">Price</dt>',
		'<dd>¥#{_price} (税込)',
		'<dt class="brand">Brand</dt>',
		'<dd>#{brand_name}</dd>',
		'</dl>',
		'<ul class="utility#{_disable_class}">',
		'<li class="cart">#{_cart_button}</li>',
		'</ul>',
		'</div>'
	].join('');
};

BEYES.Unit.Zakka.addToCart = function(id) {
	var item = stash.data[id];
	if (!item) return;

	BEYES.QuickCart.add(item);
	$(this).parents('.tooltipZak01').hide();
	return false;
};

BEYES.Unit.Zakka.prototype = {
	_item: function() {
		var o = this.o;
		var item = o.item;
		item._disable = (item.sold_out_flag || item.coming_soon_flag || item.status == 5);
		item._permalink = '/zakka/item/'+item.id;
		item._unit_type = ((o.count + 1) % 16).toFormatString();
		item._unit_style = (o.count != null && (o.count + 1) % (o.column || 6) == 0) ?
			' style="margin-right:0"' :
			'';
		item._disable_class = item._disable ? ' disable' : '';
		item._state = item.new_flag ? '<div class="new">New</div>' : '';
		item._cart_button = item._disable ?
			'<span/>' :
			'<a href="#" onclick="return BEYES.Unit.Zakka.addToCart.call(this, #{id})/>';
	},

	show: function() {
		var self = this;
		var o = this.o;
		if (!o) return;

		var item = o.item;
		this._item();

		var tooltip = $(applyTemplate(this.tooltip_template, item))
			.appendTo('body')
			.mouseleave(function(e) {
				if ($(e.relatedTarget).parents().index(self.element) != -1) return;
				tooltip.fadeOut(400);
			});

		var timer = null;
		$(applyTemplate(this.template, item))
			.appendTo(o.container)
			.hover(
				function(e) {
					if (tooltip.is(':visible')) return;
					var self = $(this);
					timer = setTimeout(function() {
						tooltip
							.css({
								top : self.offset().top - 136,
								left: self.offset().left - 22
							})
							.fadeIn(200);
					}, 400);
				},
				function(e) {
					if ($.browser.msie && e.toElement == tooltip[0]) return;
					else
						if (e.relatedTarget == tooltip[0]) return;
					if (timer) clearTimeout(timer);
					tooltip.fadeOut(400);
				}
			);
	}
};


BEYES.UnitList = function(settings) {
	this.settings = $.extend({
		container: $('#unitMainList01'),
		api      : '/api/product/search',
		queries  : {},
		paginate : false,
		permanent: false,
		column   : 0,

		pagerContainer: null,
		items         : null,
		totalItem     : 0
	}, settings);
	this.loading_id = 0;
	this.parameter = null;

	this.init();
};

BEYES.UnitList.update = function(p) {}; // External Interface
// for compatibility
BEYES.ItemList = {};
BEYES.ItemList.update = function(p) { BEYES.UnitList.update(p); };

BEYES.UnitList.prototype = {
	init: function(raw) {
		var s = this.settings;

		// when location.hash is changed, break a title in IE.
		if ($.browser.msie) document.title = stash.title;

		if (s.permanent)
			$.override(s.queries, raw || BEYES.parameter.get() || {});
	},

	request: function() {
		var self = this;
		var s = this.settings;

		var loading_id = this.loading_id = new Date().getTime();

		var q = $.extend(true, {}, s.queries);
		criteria = q.criteria;
		if (criteria) q.criteria = this.criteria(criteria);

		var key = MD5.calc($.param(q));
		var data = stash.data[key];
		if (data)
			this.success(data, loading_id);
		else {
			s.container.html('<p class="loading">connecting...</p>');
			$.getJSON(s.api, q, function(data) {
				if (data.error) throw new Error('Response includes error flag.');

				stash.data[key] = data;
				self.success.call(self, data, loading_id);
			});
		}
	},

	success: function(data, loading_id) {
		if (loading_id < this.loading_id) return; // only latest request
		var request_id = loading_id;

		var s = this.settings;
		s.items = $.grep(data.result.data, function(item) {
			if (!stash.data[item.id]) stash.data[item.id] = item;			
			return !!item; // ignores property when value is undefined
		});
		var p = data.result.pager;
		var c = s.queries.criteria;
		if (p && c) {
			c.offset    = p.offset;
			c.limit     = p.limit;
			s.totalItem = p.total;
		}

		this.show(request_id);
	},

	show: function(request_id) {
		var self = this;
		var s = this.settings;
		var container = s.container;
		if (!(container && container.length)) return;
		var items     = s.items;
		var paginate  = s.paginate;
		var queries   = s.queries;
		var parameter = this.parameter = BEYES.parameter.make(queries);
		if (!items) { this.request(); return parameter; } // loop
		var item_length = items.length;

		var row = item_length ? 188 * Math.ceil(item_length / s.column) : '';
		container
			.height(row)
			.empty();

		if (s.permanent) BEYES.parameter.update(queries);

		if (paginate) {
			var p = s.pagerContainer;
			var top    = (paginate === true || paginate === 'top');
			var bottom = (paginate === true || paginate === 'bottom');
			var pager = this.pager();
			if (pager) {
				if (!p) {
					p = s.pagerContainer = {};
					var template = $('<div class="navPage"/>');
					if (top) p.top = template.clone().insertBefore(container);
					if (bottom) p.bottom = template.clone().insertAfter(container);
				}

				if (top)
					p.top.html(pager.clone(true));
				if (bottom) {
					p.bottom.html(pager.clone(true));

					var will = container.offset().top - 100;
					if ($(window).scrollTop() > will)
						Deferred.next(function() {
							$(window).scrollTop(will);
						});
				}
			}
			else if (p) {
				if (p.top) p.top.remove();
				if (p.bottom) p.bottom.remove();
				delete s.pagerContainer;
			}
		}

		if (!item_length) {
			if (BEYES.type() == 'zakka')
				container.html('<p class="noItem">申し訳ありませんが、<br/>該当する商品はございません。</p>');
			if (this.complete) this.complete(true);
			return parameter;
		}

		this
			.append(request_id)
			.next(function() {
				if (request_id && request_id != self.loading_id) throw 'Stopped. Not latest request.';
				if (self.complete) self.complete.call(self);
			})
			.error(function(e) {
				log(e);
			});

		return parameter;
	},

	// return the Deferred object
	append: function(request_id) {
		var self = this;
		var s = this.settings;
		var container = s.container;
		var items     = s.items;
		var column    = s.column;

		return Deferred.loop(items.length, function(i) {
			if (request_id && request_id != self.loading_id) throw 'Stopped. Not latest request.';

			var item = items[i];
			new BEYES.Unit({
				container: container,
				item     : item,
				count    : i,
				column   : column || null
			}).show();
		});
	},

	complete: null,

	rebase: function(queries) {
		this.settings.items = null;
		this.init(queries);
		return this.show();
	},

	criteria: function(c) {
		c = $.extend({
			sortColumns: [{
				column   : 'SellingDate',
				direction: 'Descending'
			}],
			offset     : 0,
			limit      : 18
		}, c || {});

		for (var k in c.condition || {}) {
			var v = c.condition[k];
			if (v) c.condition[k] = (typeof v == 'object') ? v : { Equal: v };
		}
		return JSON.stringify(c);
	},

	pager: function() {
		var self = this;
		var c = this.settings.queries.criteria;

		var total_page = Math.ceil(this.settings.totalItem / c.limit);
		if (!total_page) return null;
		var current_page = Math.floor(c.offset / c.limit) + 1;

		var ul = $([
			'<ul class="pager">',
			'<li class="number"/>',
			'</ul>'
		].join(''));
		var li = $('li', ul);

		var span = $('<span/>');
		var a    = $('<a href="#"/>').click(function() {
			self.rebase({
				criteria: {
					offset: ($(this).text() - 1) * c.limit
				}
			});
			return false;
		});

		var i = 5;
		var n = Math.min(Math.max(i, current_page + Math.floor(i / 2)), total_page);
		while (i-- && n) {
			li.prepend((n == current_page ? span : a).clone(true).text(n));
			n--;
		}

		var zakka = config.type == 'zakka';
		if (current_page > 1) {
			var src = zakka ? '/img/zak/nav_prev_01.png' : '/img/common/nav_prev_01.png';
			$([
				'<li class="prev">',
				'<a href="#">',
				'<img src="'+src+'" alt="Prev" width="63" height="16"/>',
				'</a>',
				'</li>'
			].join(''))
				.prependTo(ul)
				.find('a').click(function() {
					self.rebase({
						criteria: {
							offset: (current_page - 2) * c.limit // 0 starting
						}
					});
					return false;
				}).find('img').roll();
		}
		if (current_page < total_page) {
			var src = zakka ? '/img/zak/nav_next_01.png' : '/img/common/nav_next_01.png';
			$([
				'<li class="next">',
				'<a href="#">',
				'<img src="'+src+'" alt="Next" width="63" height="16"/>',
				'</a>',
				'</li>'
			].join(''))
				.appendTo(ul)
				.find('a').click(function() {
					self.rebase({
						criteria: {
							offset: current_page * c.limit
						}
					});
					return false;
				}).find('img').roll();
		}

		return ul;
	}
};


BEYES.GenreList = new Class({
	initialize: function(queries) {
		this.constractor.SUPER.call(this, {
			api      : '/api/product/searchGenre',
			queries  : $.extend({
				page_type: 1
			}, queries),
			paginate : 'bottom',
			permanent: true
		});
	},

 	success: function(data, loading_id) {
		if (loading_id < this.loading_id) return; // only latest request
		var request_id = loading_id;

		var s = this.settings;
		var genres = data.result.data;
		var length = genres.length;
		s._genreLength = length;
		s.column       = (length > 1) ? 1 : 3;

		var obj = {}, length = 0;
		for (var n in genres) {
			if (/[^\d]/.test(n)) continue;
			var genre = genres[n];
			var l = genre.length;
			obj[n] = genre; // converts Array to Object for a cache interface
			length = Math.max(l, length);

			for (var i = 0; i < l; i++) {
				var item = genre[i];
				if (!stash.data[item.id]) stash.data[item.id] = item;
			}
		}
		obj.length = length;
		s.items = obj;

		var p = data.result.pager;
		var c = s.queries.criteria;
		if (p && c) {
			c.offset    = p.offset;
			c.limit     = p.limit;
			s.totalItem = p.max_length || p.total;
		}

		this.show(request_id);
	},

	// return the Deferred object
	append: function(request_id) {
		var self = this;
		var s = this.settings;
		var container    = s.container;
		var genres       = s.items;
		var genre_length = s._genreLength;
		var column       = s.column;

		var i = 1;
		var thread = [];
		for (var n in genres) (function(n) {
			if (/[^\d]|[124]/.test(n)) return; // skip noise, 1, 2, 4

			var items = genres[n];
			var c = genre_length > 1 ?
				$('<div class="unitGroup"/>').appendTo(container) :
				container;
			if (i == genre_length || i % 3 == 0) c.css('margin-right', 0);
			if (items.length)
				thread.push(
					Deferred.loop(items.length, function(i) {
						if (request_id && request_id != self.loading_id) throw 'Stopped. Not latest request.';

						new BEYES.Unit({
							container: c,
							item     : items[i],
							count    : i,
							column   : column
						}).show();
						// var wait_time = stash.requested ? 0 : (i <= 9 ? 0 : 0.25); // keep a flash animation resource
						return Deferred.wait(0);
					})
				);
			else
				c.html('&nbsp;');

			i++;
		})(n);
		return Deferred.parallel(thread);
			// .parallel(thread)
			// .next(function() {
			// 	stash.requested = true;
			// });
	},

	complete: function() {
		BEYES.Logging.unitList($.extend({
			genre      : '',
			category   : '',
			subcategory: '',
			brand      : '',
			span       : '',
			limit      : '',
			offset     : ''
		}, this.parameter));
	}
}, BEYES.UnitList);


BEYES.showRankList = function(container) {
	var type = BEYES.type();
	var path = BEYES.imagePath();
	$.each(stash.ranking.result.data, function(k) {
		var width, color;
		switch (config.type) {
			case 'men':
				width = 120;
				color = k % 2 ? 'og' : 'bk';
				break;
			case 'women':
				width = 80;
				color = k % 2 ? 'gn' : 'gr';
				break;
		}
		var element = $([
			'<div class="contRanking">',
			'<h2><img src="'+path+'/ranking/ttl_'+k+'_01.png" alt="'+BEYES.category(k).name+'" width="'+width+'" height="14"/></h2>',
			'<div class="itemList"/>',
			'</div>'
		].join(''))
			.appendTo(container)
			.addClass(k % 2 ? 'odd' : 'even')
			.find('img').pngfix().end();

		$.each(this, function(i, item) {
			var permalink = '/'+BEYES.getType(item.gender_type)+'/item/'+item.id;
			var rank = i + 1;

			var dl = $('<dl class="item"/>').appendTo($('.itemList', element));
			if (!(rank % 3)) dl.css('margin-right', 0);
			if (i < 3) {
				var r = item.ranking_history ?
					rank < item.ranking_history ? '↑' : rank == item.ranking_history ? '→' : '↓' :
					'―';
				dl.addClass('top3').html([
					'<dt class="rankNumber">',
					'<img src="'+path+'/ranking/txt_rank_no'+rank+'_'+color+'_01.png" alt="'+rank+'" width="73" height="45"/>',
					'<span class="lastRank">先週'+(item.ranking_history || '―')+'位（'+r+'）</span>',
					'</dt>',
					'<dd/>'
				].join(''));
				new BEYES.Unit({
					container: $('dd', dl),
					item     : item
				}).show();
			}
			else
				dl.addClass('lower').html([
					'<dt class="rankNumber"><img src="'+path+'/ranking/txt_rank_no'+rank+'_'+color+'_01.png" alt="'+rank+'" width="29" height="16"/></dt>',
					'<dd><a href="'+permalink+'">'+item.name+'</a></dd>'
				].join(''));
		});
	});
};


BEYES.WomenCategoryTab = function t() {
	var unitList;
	var tab_width = [95, 94, 94, 95, 94, 94, 95, 94, 94, 96];
	var current;
	var current_src;
	var selected;
	var selected_src;
	var queries = {
		criteria: {
			condition: { WomenCategory: null }
		}
	};

	return {
		init: function() {
			unitList = new BEYES.UnitList({
				queries  : {
					criteria : {
						condition  : { GenderType: BEYES.getTypeId() },
						sortColumns: [
							{ column: 'Toppage', direction: 'Ascending' },
							{ column: 'SellingDate', direction: 'Descending' }
						],
						limit      : 60
					},
					page_type: 1
				},
				permanent: true,
				paginate : 'bottom',
				column   : 3
			});
		},

		setup: function() {
			t.init();
			t.show()
				.mousemove(t.over)
				.mouseleave(t.out)
				.click(t.select);
			var i = unitList.settings.queries.criteria.condition.WomenCategory || 0;
			var e = { target: $('img', container)[i] };
			t.over(e);
			t.select(e);
			queries.criteria.offset = 0;
		},

		show: function() {
			var template = [];
			$.each(tab_width, function(i) {
				var n = (i + 1).toFormatString();
				var src = '/img/wom/nav_category_'+n+'.png';
				var alt = i ? BEYES.category(i) : '新着';
				template.push('<li><a href="#"><img src="'+src+'" alt="'+alt+'" width="'+this+'" height="26" class="tab-'+i+'"/></a></li>');
			});
			template = '<ul>'+template.join('')+'</ul>';

			current      = null;
			current_src  = null;
			selected     = null;
			selected_src = null;

			return $(template).appendTo('#navWomSub');
		},

		over: function(e) {
			var img = e.target;
			if (img == current) return false;
			var src = img.src;

			if (current && current != selected) current.src = current_src;
			current     = img;
			current_src = src;
			if (img == selected) return false;
			img.src = src.replace(/(\.[^.]+$)/, '_o$1');
			return false;
		},

		out: function(e) {
			var img = e.target;
			if (img == selected) return false;

			current.src = current_src;
			current     = null;
			current_src = null;
			return false;
		},

		select: function() {
			if (current == selected) return false;
			if (selected) {
				selected.src = selected_src;
				$(selected).css('cursor', '');
				t.out({ target: selected });
			}
			selected     = current;
			selected_src = current_src;
			$(current).css('cursor', 'default');

			var n = Number(current.className.slice(4));
			queries.criteria.condition.WomenCategory = n || null;
			unitList.rebase(queries);
			return false;
		}
	};
};


BEYES.Viewer = function(container) {
	this.container = container || $('#prdImg');
};
BEYES.Viewer.prototype = {
	show: function() {
		var xml = stash.xml.reverse();
		for (var i = 0, length = xml.length; i < length; i++) {
			if (i + 1 == length && stash.caption)
				$('<p class="descPrdMainImg"/>').text(stash.caption).prependTo(this.container);

			$('<div id="prdMainImg'+i.toFormatString()+'"/>')
				.prependTo(this.container)
				.fl({
					src      : '/swf/src/zoomify_default.swf',
					width    : 455,
					height   : 455,
					flashvars: { xmlPath: xml[i] }
				});
		}
	}
};


BEYES.QuickCart = (function() {
	var container = null;
	var timer = null;
	var opened = false;

	return {
		setup: function() {
			$('.cart01').each(function(i) {
				var container = $(this);
				if (container.children().length || !(stash.itemColor || stash.itemSize)) return;

				var k = {}, v = {};
				if (stash.itemColor) {
					k.color = getKey(stash.itemColor);
					v.color = getValue(stash.itemColor);
					container.pulldown(v.color, 'selectbox02');
				}
				if (stash.itemSize) {
					k.size = getKey(stash.itemSize);
					v.size = getValue(stash.itemSize);
					container.pulldown(v.size, 'selectbox02');
				}
				$('<p class="btnAddCart"><input type="image" alt="カートに入れる"/></p>')
					.appendTo(container)
					.find('input')
						.attr('src', BEYES.imagePath()+'/btn_add_cart_'+(i + 1).toFormatString()+'.png')
						.roll()
						.click(function() {
							var id = [stash.id];

							$.each(['color', 'size'], function(i, menu) {
								var current = $('.current', container).eq(i).text();
								var i = $.inArray(current, v[menu]);
								if (i == -1) return false;
								id.push(k[menu][i]);
							});
							id = id.join('');

							var q = { id: stash.id };
							$.getJSON('/api/product/get', q, function(data) {
								if (data.error) throw new Error('Response includes error flag.');
								var item = data.result.data[0];
								item.id = id;
								BEYES.QuickCart.add(item, { events: 'event4' });
							});
							return false;
						});

				$([
					'<p class="btnSaveItem">',
					'<a href="/'+config.type+'/cart?wish_product_id='+stash.id+'#wish'+stash.id+'"><img/></a>',
					'</p>'
				].join(''))
					.appendTo(container)
					.find('img')
						.attr({
							src   : '/img/common/btn_save_item_'+(i + 1).toFormatString()+'.png',
							width : i ? 122 : 102,
							height: 20,
							alt   : 'この商品を保存'
						})
						.roll()
						.end();
			});
			BEYES.QuickCart.append();

			$('.cart01')
				.addClass('type02')
				.css('top', $('#prdHeader, #zakHeader .inner').height() / 2 - $('.type02').height() / 2 + 3);
		},

		append: function() {
			container = $('<div id="quickCart"><div id="swfCartBox"/></div>')
				.appendTo('body')
				.find('#swfCartBox').fl({
					src             : '/swf/src/cart.swf',
					width           : '100%',
					height          : 275,
					flashvars       : { category: config.type },
					expressInstaller: null
				}).end();

			if ($.browser.msie6) {
				container.css({
					bottom   : 'auto',
					marginTop: 241
				});
				$(window).bind('scroll resize', function() {
					var bottom = $(window).scrollTop() + $(window).height();
					container.css('top', bottom - 275);
				});
			}
		},

		add: function(item, options) {
			$('#swfCartBox').fl().addItem(item.id);

			BEYES.Logging.addToQuickCart(item, options);

			if (timer) {
				clearTimeout(timer);
				$('#txtAddedCart').hide().fadeIn();
			}
			if (opened) {
				$('#txtAddedCart').remove();
				return;
			}

			var message = $('#txtAddedCart');
			if (!message.length) {
				message = $('<div id="txtAddedCart"><p>商品が追加されました</p></div>').appendTo('body');
				if ($.browser.msie6) {
					$(window)
						.bind('scroll resize.cart', function() {
							var bottom = $(window).scrollTop() + $(window).height();
							message.css('top', bottom - 115);
						})
						.trigger('resize.cart');
					message.hide().fadeIn();
				}
				else
					message
						.css({
							bottom: 25,
							opacity: 0
						})
						.animate({
							bottom: 35,
							opacity: 1
						});
			}
			var f = $.browser.msie6 ?
				function() {
					message.fadeOut(function() { $(this).remove(); });
				} :
				function() {
					message.animate({
						bottom : 45,
						opacity: 0
					}, function() { $(this).remove(); });
				};
			timer = setTimeout(f, 1000 * 3.5);
		},

		remove: function(id) { // External Interface
			if (!id) return;

			var q = { id: id.toString().slice(0, 6) };
			$.getJSON('/api/product/get', q, function(data) {
				if (data.error) throw new Error('Response includes error flag.');
				var item = data.result.data[0];

				BEYES.Logging.dynamic({
					products: hash.values({
						category : '',
						sku      : item.id,
						count    : 1,
						sub_total: item.sale_flag ? item.sale_list_price : item.list_price,
						events   : '',
						evar     : 'evar42=31'+item.kikaku_id
					}).join(';'),
					events  : 'event11',
					prop45  : '小プレカートから商品を削除',
					channel : ['カート操作']
				});
			});
		},

		toggle: function(open) {
			var o = { height: 275 };
			var c = { height: 34 };
			if ($.browser.msie6) {
				o.marginTop = 0;
				c.marginTop = o.height - c.height;
			}
			opened = open;
			opened ?
				setTimeout(function() {
					clearTimeout(timer);
					$('#txtAddedCart').remove();
					container.animate(o, { easing: 'easeOutCubic' });

					BEYES.Logging.dynamic({
						prop45 : '小プレカートを開く',
						channel: 'カート操作',
						events : null
					});
				}, 0) :
				setTimeout(function() {
					container.animate(c, { easing: 'easeOutCubic' });
				}, 0);
		}
	};
})();


BEYES.Logging = (function() {
	var channel = null;
	var events  = null;

	new function() {
		var channel_table = {
			'^/$': ['トップ'],
			'/(?:genre|category)/$': 'J一覧',
			'/item/\\d+$': ['詳細'],
			'/cart': ['カート'],
			'^/buyer/': 'メルマガ',
			'^/buyerblog/': ['ブログ'],
			'^/news/': 'ニュース',
			'^/recommend/': 'RECOMMEND',
			'^/(?:about|guide|specialcustomer|recruit|affiliate|bbrains|corporate|privacy|editwall|account|men/campaign)/': 'バイズについて',
			'/brand/$': 'ブランド一覧',
			'/brand/\\d+$': 'ブランドページ',
			'/brand/info/\\d+$': 'ブランド別info',
			'/ranking/$': 'ランキング'
		};
		var events_table = { // for static send
			'/item/\\d+$': 'prodView,scRemove',
			'^/$': 'event1',
			'^/buyer/change/$': 'event10',
			'^/buyer/$': 'event10',
			'^/buyer/complete$': 'event16'
		};

		var find = function(data) {
			var c = '';
			var path = location.pathname;
			$.each(data, function(k, v) {
				if (new RegExp(k).test(path)) {
					c = v;
					return false;
				}
			});
			return c;
		};
		channel = find(channel_table);
		events  = find(events_table);
	};

	return {
		page: function() {
			if (typeof s == 'undefined') return;
			if (s.prop45 && !stash.logging)
				stash.logging = {
					prop45: s.prop45,
					prop46: s.prop46,
					prop49: s.prop49
				};

			var page_name;
			if (parseQuery()) { // TODO tmp
				var queries = BEYES.parameter.get();
				var type = BEYES.type() || 'men';
				var p = $.extend({
					type       : type.capitalize(),
					channel    : channel,
					genre      : '',
					category   : '',
					subcategory: '',
					brand      : '',
					span       : '',
					limit      : '',
					offset     : ''
				}, BEYES.parameter.make(queries));
				if (p.genre) p.genre = BEYES.genre(p.genre).name;
				if (p.category) {
					var c = BEYES.category(p.category, type);
					p.category = c.name;
					if (p.subcategory)
						p.subcategory = c.sub[p.subcategory - 1];
				}
				if (p.brand) {
					var b = BEYES.brand(p.brand, type);
					// console.log(p.brand, type,b);
					p.brand = b.name;
				}
				page_name = hash.values(p).join(';');
			}
			// console.log(queries, page_name);
			this.send(page_name);
		},

		unitList: function(p) {
			if (stash.skip_logging) {
				stash.skip_logging = false;
				return;
			}
			p = p || {};
			var type = BEYES.type() || 'Men';
			p = $.extend({
				type   : type.capitalize(),
				channel: channel
			}, p);

			// console.log('p', $.extend({}, p));
			if (p.genre) p.genre = BEYES.genre(p.genre).name;
			if (p.category) {
				var c = BEYES.category(p.category, type);
				p.category = c.name;
				if (p.subcategory)
					p.subcategory = c.sub[p.subcategory - 1];
			}
			if (p.brand) {
				var b = BEYES.brand(p.brand, type);
				p.brand = b.name;
			}

			// console.log('unitList query', p);

			this.dynamic({
				prop45: getValue(p).join(';')
			});
		},

		addToQuickCart: function(item, options) {
			var pathname = location.pathname;
			BEYES.Logging.dynamic($.extend({
				products: hash.values({
					category : '',
					sku      : item.id,
					count    : 1,
					sub_total: (item.sale_flag ? item.sale_list_price : item.list_price),
					events   : '',
					evar     : 'evar42=31'+item.kikaku_id
				}).join(';'),
				events  : (
					/\/item\/\d+$/.test(pathname) ? 'event5' :
					/\/category\//.test(pathname) ? 'event2' :
					/\/brand\//.test(pathname)    ? 'event3' :
					'scOpen'
				),
				prop45  : '小プレカートに入れる',
				channel : ['カート操作']
			}, options));
		},

		dynamic: function(options) {
			if (typeof s == 'undefined') return;
			var type = BEYES.type();

			s_objectID = 'contents';
			var account = /(?:www\.)beyes\.jp/.test(location.hostname) ?
				'lightupbeyesjp' :
				'lightupdev2';
			var d = s_gi(account);
			d.channel = options.channel || channel;
			if ($.isArray(d.channel)) {
				if (type) d.channel.unshift(type.capitalize());
				d.channel = d.channel.join('~');
			}
			d.products = options.products;
			d.prop45   = d.eVar45 = options.prop45; // pageName
			d.prop46   = ':'+d.prop45;
			if (options.events !== null)
				d.events = options.events || events;
			else
				delete d.events;

			var engine = getEngineAndKW(document.URL, document.referrer, 'cid');
			if (engine) {
				d.prop32 = d.eVar32 = 'E('+engine+');';
				d.prop46 = 'E('+engine+');';
			}
			else {
				if (d.campaign) {
					d.prop32 = d.eVar32 = 'C('+d.campaign+');';
					d.prop46 = 'C('+d.campaign+');';
				}
				else
					d.prop32 = d.eVar32 = '';
			}
			delete d.pageName;

			// console.log('dynamic query', $.extend({}, d), options);

			d.tl(d, 'o', d.prop45); // ! confirm the s_code.js too
		},

		send: function(page_name, c) {
			if (typeof s == 'undefined') return;
			channel = c || channel;

			var type = BEYES.type();
			var key = store.save({
				pageName: s.pageName,
				channel : s.channel,
				events  : s.events
			});

			this.parse_cookie();
			if (page_name || page_name == '') s.pageName = page_name;
			if (/\/brand\/info\/\d+$/.test(location.pathname))
				s.pageName = 'i:'+s.pageName;

			if ($.isArray(channel)) {
				if (type) channel.unshift(type.capitalize());
				channel = channel.join('~');
			}
			s.channel = channel;
			s.events  = events;

			s.prop17 = s.eVar17 = s.zip;

			// console.log('static query', $.extend({}, s));

			s_code = s.t();
			if (s_code) document.write(s_code);

			$.extend(s, store.restore(key));
		},

		parse_cookie: function(cookie) {
			if (typeof s == 'undefined') return;
			cookie = cookie || $.cookie('lusc_SCID');
			if (!cookie) return;
			cookie = 'scid='+cookie;
			$.extend(s, parseQuery('#'+cookie)); // TODO bad interface..
		}
	};
})();


$(function() {
	$('.btn').roll();
	$('a[rel="external"], area[rel="external"]').external();
	$('a[href="#top"]').click(function() {
		$().scrollTop(0);
		return false;
	});
	$('a.imagebox').imagebox();

	$('.navUtility > li.tree').each(function() {
		var ul  = $('ul', this);
		var img = $('> a > img', this)[0];
		var out  = img.src;
		var over = out.replace(/(\.[^.]+$)/, '_o$1');
		$(this).hover(
			function() {
				img.src = over;
				ul.slideDown(100);
			},
			function(e) {
				img.src = out;
				ul.slideUp(100);
			}
		);
	});

	$('div[class*="item-"]').each(function() {
		var self = this;
		var id = /\bitem-([\d-]+)\b/.exec(this.className);
		if (!id[1]) return;

		id = id[1].split('-');
		new BEYES.UnitList({
			container: $(this),
			queries  : {
				criteria : {
					condition: {
						Id        : { In: id },
						GenderType: BEYES.type()
					}
				},
				page_type: 5
			},
			column   : id.length
		}).show(function() {
			$('> div', self).css('margin-top', 0);
		});
	});

	if (BEYES.setup) BEYES.setup();

	BEYES.Logging.page();
});

if (window.sessionStorage)
	$(window).unload(function() {
		storage('data', stash.data);
	});
