$.fn.byotooltip=function(b){var c=150;return this.each(function(){var a='tt'+Math.floor(Math.random()*9999999);$('<div id="'+a+'" class="tooltip" '+b.extra+'><span>'+b.content+'</span></div>').css({opacity:0,left:'-9999em'}).appendTo('#tooltips');$(this).attr('rel',a).mouseenter(function(){$('#'+a).css({left:($(this).position().left-$('#'+a).width()/2)+'px'}).animate({top:'+=20px',opacity:1},c)}).mouseleave(function(){$('#'+a).animate({top:'-=20px',opacity:0},c,'linear',function(){$(this).css('left','-9999em')})})})};

function _ (str) {
	return (typeof translations[str] !== 'undefined') ? translations[str] : str;
}

var byo3 = function (id) {
	var $$ = $('#' + id);
	var self = this;

	// path to img dir
	this.domain = '//static.fleshjack.com';
	this.host   = this.domain + '/images/dyo/3.0';

	// product ids!
	this.ids = {
		'original': 569
		,'textured': 1349
		// @blue-case-special
		//,'blue-original': 3945
		//,'blue-textured': 3946
		// @blue-case-special
		// @iceblowout
		//,'ice-both': 4085
		// @iceblowout
	};

	// widths of things in various states
	this.d = {
		group: {
			normal: '745px',
			final: '784px'
		},
		panel: {
			normal: '675px',
			final: '715px'
		},
		title: {
			normal: '70px',
			next: '80px',
			collapsed: '41px'
		}
	};
	// offsets for the panel to make room for the title
	this.o = {
		panel: {
			normal: '70px',
			next: '80px',
			collapsed: '41px'
		},
		byo: {
			normal: '559px',
			review: '622px'
		},
		next_callout: {
			normal: '-552px',
			next: '-575px',
			x: '-354px'
		}
	};

	// internal vars
	this.shot   = '';
	this.config = {
		'case':    'black',
		'orifice': 'pink-jack-ass',
		'texture': 'original'
	};
	this.review = false;
	this.cart = [];
	this.cart_prices = {};

	// panel animation speed
	this.speed = 600;

	// crossfade speed
	this.fade  = 150;

	// have they specifically clicked?
	this.has_interacted = false;

	// currency matching
	this.expr_currency = /&[^;]+;|[^0-9\.]/;

	// set up the items per group
	this.options = {
		cases: {
			'black':  { sku: '002110' },
			'clear':  { sku: '002210' },
			'silver': { sku: '002610' },
			'blue':   { sku: '002800' }
		},
		orifices: {
			'pink-jack-ass':  { sku: '02' },
			'pink-mouth':     { sku: '03' },
			'pink-butt':      { sku: '01' }
/*
			'pink-stealth':   { sku: '04' }
			'ice-jack-ass': { sku: '22' },
			'ice-mouth':    { sku: '23' },
			'ice-butt':     { sku: '21' },
			'ice-stealth':  { sku: '24' }
*/
		},
		textures: {
			'original':     { sku: '0' },
			'super-tight':  { sku: '1' },
			/*'ultra-tight':  { sku: '2' },*/
			'wonder-wave':  { sku: '3' },
			'speed-bump':   { sku: '5' },
			'super-ribbed': { sku: '4' },
			'vortex':       { sku: '8' }
		}
	};

	// converts step to label
	this.steps = {
		0: 'case',
		1: 'orifice',
		2: 'texture'
	};

	/*
	* speciality price situations
	*/

	// @blue-case-special
	this.get_fucking_blue_price = function () {
		if (this.config['case'] === 'blue') {
			return (this.config.texture !== 'original')
				? price['blue-textured']
				: price['blue-original'];
		}
		else {
			return (this.config.texture !== 'original')
				? price['textured']
				: price['original'];
		}
	};
	this.fucking_blue_price_shit = function (casecolor, type, target) {
		if (casecolor === 'blue') {
			return (type === 'texture' && target !== 'original')
				? price['blue-textured']
				: price['blue-original'];
		}
		else {
			return (type === 'texture' && target !== 'original')
				? price['textured']
				: price['original'];
		}
	};
	// @blue-case-special

	// @iceblowout
	this.get_fucking_ice_price = function () {
		if (this.config.orifice.match(/ice/)) {
			return price['ice-both'];
		}
		else {
			return (this.config.texture !== 'original')
				? price['textured']
				: price['original'];
		}
	};
	this.fucking_ice_price_shit = function (casecolor, type, target) {
		if ((type === 'orifice' && target.match(/ice/)) || this.config.orifice.match(/ice/)) {
			return price['ice-both'];
		}
		else {
			return (type === 'texture' && target !== 'original')
				? price['textured']
				: price['original'];
		}
	};
	// @iceblowout

	/*
	* business as usual
	*/

	// for keeping the price current on the review screen
	this.total = function () {
		// @iceblowout
		//var base = this.get_fucking_ice_price();
		var base = (this.config.texture !== 'original')
			? price['textured']
			: price['original'];
		// @iceblowout

		// get currency
		var currency = base.match(this.expr_currency)[0];

		// remove currency
		base = parseFloat(base.replace(this.expr_currency, ''));

		// go through cart prices and total things up
		for (var i in this.cart_prices) {
			base += parseFloat(this.cart_prices[i].replace(this.expr_currency, ''));
		}

		return currency + base.toFixed(2);
	};

	// for adding items to cart behind the scenes
	this.add = function (opts, callback) {
		var args = {
			action: 'add',
			id: '',
			referer: '/design-your-own/',
			strSKUs: '',
			intQuantity: 1
		};
		args = $.extend(args, opts);

		// add it to our internal cart so we don't add multiple quantities
		if (this.cart[args.id] !== undefined) return;
		this.cart[args.id] = 1;

		// gogo!
		$.post(
			'/shop.php',
			args,
			function () {
				if (typeof callback == 'function') callback();
			}
		);
	};

	// get rid of all byos in cart
	this.remove_byo = function () {
		for (var i in this.ids) {
			delete this.cart[this.ids[i]];
		}
		$.post('/shop.php', {
			action: 'removeProducts',
			'ids[]': this.ids
		});
	};

	// add to cart sku assembly and whisking away
	this.add_byo = function (callback) {
		var opts = {
			id: '',
			strSKUs: '',
			Option_Case: '',
			Option_Orifice: '',
			Option_Texture: ''
		};

		var _case = this.config['case'].replace(/\-(pink|ice)/, '');

		// build sku
		opts.strSKUs = [
			'000',
			this.options.orifices[this.config.orifice].sku,
			this.options.textures[this.config.texture].sku,
			',',
			this.options.cases[_case].sku
		].join('');

		// @iceblowout
		// set product id
		opts.id = this.ids[(this.config.texture === 'original' ? 'original' : 'textured')];
		/*
		if (this.config.orifice.match(/ice/)) {
			opts.id = this.ids['ice-both'];
		}
		else {
			opts.id = this.ids[(this.config.texture === 'original' ? 'original' : 'textured')];
		}
		*/
		// @iceblowout

		// set option text
		opts.Option_Case = [
			this.options.cases[_case].sku,
			'|',
			_(_case),
		].join('');
		opts.Option_Orifice = [
			'000',
			this.options.orifices[this.config.orifice].sku,
			'|',
			_(this.config.orifice),
		].join('');
		opts.Option_Texture = [
			this.options.textures[this.config.texture].sku,
			'|',
			_(this.config.texture),
		].join('');

		// add to cart!
		this.add(opts, callback);
	};

	// sets the case or orifice
	this.set = function (type, target, callback) {
		var pre = '';

		// highlight selection in the interface
		$$.find('.selectors .' + type + 's a').removeClass('selected').parent().find('.' + target).addClass('selected');

		// orifices screen?  update the manual label
		if (type === 'orifice') {
			$$.find('.selectors .' + type + 's .manual-label').removeClass('selected').filter('[class*="' + target.replace(/(pink|ice)\-/, '') + '"]').addClass('selected');
		}

		// update selection list
		$$.find('.selections .' + type + ' span').html(_(target + ' ' + type));

		// if you select a clear case, make sure the insert is correct
		if (type === 'case' && target === 'clear') {
			target = (this.config['orifice'].match(/ice/)) ? 'clear-ice' : 'clear-pink';
			var s  = $$.find('.canvas .cases div').css('background-image');

			// see if the case is already correct -- don't load new image if so
			if (s.substring(s.lastIndexOf('/') + 1, s.lastIndexOf('.png')) === target || this.shot === 'headon') return;
		}

		// if ice orifice and we're swapping textures, update color accordingly
		if (type === 'texture') {
			pre = (this.config['orifice'].match(/ice/)) ? 'ice-' : 'pink-';
		}

		// don't load stuff you don't need
		if (
			(type === 'texture' && this.shot !== 'sidecap') ||
			(type === 'orifice' && this.shot === 'sidecap')
		) {
			// noop
		}
		else {
			var path  = [this.host, '/', this.shot, '/', type, 's', '/', pre, target, '.png'].join('');
			var _self = this;

			$$.find('.spinner').show();

			$$.find('.canvas .' + type + 's div').fadeOut(_self.fade, function () {
				// swap image
				$('<img src="' + path + '" />').load(function () {
					$$.find('.canvas .' + type + 's div').css(
						'background-image',
						'url("' + path + '")'
					).fadeIn(_self.fade, function () {
						$$.find('.spinner').hide();

						// make sure the canvas is visible
						$$.find('.canvas').fadeIn(_self.fade);
					});
				});
			});
		}

		// eventually match up with sku hash table
		this.config[type] = target;

		// @iceblowout
		// update price
		/*
		$$.find('.info .price .numbers').html(
			this.fucking_ice_price_shit(this.config['case'], type, target)
		);
		*/
		$$.find('.info .price .numbers').html(
			(type === 'texture' && target !== 'original')
				? price['textured']
				: price['original']
		);
		// @iceblowout

		// when you select an orifice, make sure the clear case is correct
		if (type === 'orifice' && this.config['case'].match(/clear/)) {
			this.set('case', 'clear');
		}

		// when you select an orifice, make sure the texture is correct
		if (type === 'orifice') {
			if (target.match(/ice/)) {
				$$.find('.selectors .textures .panel').addClass('ice');
				this.set('texture', this.config['texture']);
			}
			else {
				$$.find('.selectors .textures .panel').removeClass('ice');
				this.set('texture', this.config['texture']);
			}
		}

		// remove callouts
		$$.find('.callout').fadeOut(this.fade);

		// hit up callback
		if (typeof callback == 'function') callback();

		// if it's interacted, fire next step callout
		if (this.has_interacted) {
			if ($$.find('.next-callout:visible').length) return;
			$$.find('.next-callout').css({
				'background-position': (type === 'case'
					? this.o.next_callout.x + ' ' + this.o.next_callout.normal
					: this.o.next_callout.x + ' ' + this.o.next_callout.next
				)
			}).show().animate({
				top: '330px',
				opacity: 1
			}, 1500);
		}

	};

	this.pulsate = {
		'in': function (e) {
			e.animate({
				opacity: 1
			}, 600, 'swing', function () {
				byo.pulsate['out'](e);
			});
		},
		'out': function (e) {
			e.animate({
				opacity: 0.75
			}, 600, 'swing', function () {
				byo.pulsate['in'](e);
			});
		},
		'stop': function (e) {
			e.stop().animate({opacity: 1}, 1);
		}
	};

	// sets the shot angle
	this.angle = function (target) {
		if (this.shot == target.replace(/ selected/, '')) return;

		var _self = this;

		this.shot = target;
		$$.find('.views li a').removeClass('selected').filter(':[class="' + target + '"]').addClass('selected');
		$$.find('.canvas').fadeOut(this.fade, function () {
			$(this).attr('class', 'canvas ' + target);
			var _this = this;

			_self.set('case',    _self.config['case']);
			_self.set('orifice', _self.config['orifice']);
			_self.set('texture', _self.config['texture']);
		});
	};

	// changes the step
	this.step = function (target) {
		// are we in the review phase?  if so, go back to the old interface
		if (this.review === true) {
			this.review = false;

			// bring back progress and buy/price buttons
			$$.find('.info .progress .bar, .info .price').fadeIn(self.fade);
			$$.find('.info').animate({
				height: '+=50px'
			}, self.fade);

			// fade out review panel and bring in selectors
			$$.find('.review, .progress .done, .info .change').fadeOut(self.fade, function () {
				$$.find('.selectors').fadeIn(self.fade, function () {
					$$.css('height', self.o.byo.normal);
				});
			});

			// remove from cart
			this.remove_byo();
		}

		// change the progress bar
		$$.find('.progress .bar div').attr('class', this.steps[target]);

		// update state for groups
		var set = $$.find('.selectors .group').removeClass('next collapsed');
		set.filter(':not(:eq(' + target + '))').addClass('collapsed');
		set.filter(':eq(' + target + ')').next(':first').removeClass('collapsed').addClass('next');

		// animate less
		set.filter('.collapsed').animate({
			width: this.d.title.collapsed
		}, this.speed).find('.panel').animate({
			left: this.o.panel.collapsed
		}, this.speed);

		// animate current
		set.filter(':eq(' + target + ')').animate({
			width: (target === 2 ? this.d.group.final : this.d.group.normal)
		}, this.speed).find('.panel').animate({
			left: this.o.panel.normal
		}, this.speed);

		// animate future
		set.filter('.next').animate({
			width: this.d.title.next
		}, this.speed).find('.panel').animate({
			left: this.o.panel.next
		}, this.speed);

		// set the view
		if (target === 0) this.angle('fortyfive');
		if (target === 1) this.angle('headon');
		if (target === 2) this.angle('sidecap');

		// pulsate next button
		this.pulsate['stop']($$.find('.selectors a.title, .selectors .group a.final'));
		this.pulsate['out']($$.find('.selectors .next a.title'));

		if (target === 2) this.pulsate['out']($$.find('.selectors .group a.final'));

		// reset interaction
		this.has_interacted = false;
		$$.find('.next-callout').animate({
			top: '260px',
			opacity: 0
		}, 1500, 'linear', function () {
			$(this).hide();
		});
	};

	// create upsell markup
	this.create_upsells = function (index, e) {
		// wipe out anything in there
		$(e).find('.products').html('');

		// upsells, assemble!  hoooooo
		for (var i in upsells[index]) {
			var item = upsells[index][i];
			var str = [
				'<div class="product ' + (this.cart[item.id] !== undefined ? 'selected' : '') + '">',
				'<img src="' + this.domain + '/images/products/thumb_' + item.id + '.jpg" height="100" width="100" alt="' + item.title + '" />',
				'<span class="title">' + item.title + '</span>',
				'<span class="price">' + item.price + '</span>',
				'<a href="javascript:;" class="add">Add this</a>',
				'</div>'
			];

			// add click event
			$(str.join('')).find('.add').data('info', {
				strSKUs: item.sku,
				id: item.id,
				title: item.title,
				price: item.price
			}).click(function () {
				// add to cart prices for totaling
				self.cart_prices[$(this).data('info').id] = ($(this).data('info').price);

				self.add({
					strSKUs: $(this).data('info').strSKUs,
					id: $(this).data('info').id
				}, function () {
					$$.find('.review .price .numbers').html(self.total());
				});

				// make sure to remove the ability to add again, and set things visually
				$(this).unbind().parent().addClass('selected');
			}).parent().appendTo($(e).find('.products'));
		}
	};

	/*
	 * constructor
	 */

	// draws in all of the items per group
	for (var group in this.options) {
		var str = [];
		var group_name = group.substr(0, group.length - 1);

		for (var item in this.options[group]) {
			str.push([
				"<a onclick=\"byo.set('", group_name, "', '", item,"', function () { byo.has_interacted = true; });\" href=\"javascript:;\" class=\"", item,"\"><span class=\"image\"></span><span class=\"label\">", _(item), "</span></a>"
			].join(''));
		}

		// extra step if these are orifices -- we need to draw labels at the bottom manually
		if (group === 'orifices') {
			str.push('<div class="manual-labels">');
			for (var item in this.options[group]) {
				if (item.match(/pink/)) {
					item_class = item.replace(/(ice|pink)\-/, '');
					str.push([
						'<span class="manual-label ', item_class,'">', _(item_class), '</span>'
					].join(''));
				}
			}
			str.push('</div>');
		}

		// extra step for textures -- tooltips
		if (group === 'textures') {
			str.push('<script type="text/javascript">');
			for (var item in this.options[group]) {
				//str.push('$(".group.' + group + ' .panel .' + item + '").tooltip({extra: \'style="top: 260px;"\', content: "' + _('tooltip-' + item) + '"});');
			}
			str.push('</script>');
			$$.find('.tooltips').html(str.join(''));
		}

		$$.find('.group.' + group + ' .panel').prepend(str.join(''));
	}

	// add click events for switching steps @todo consolidate this idiotic code
	$$.find('.bar a.one, .group .title:eq(0), .selections li span:eq(0)').click(function ()   { self.step(0); });
	$$.find('.bar a.two, .group .title:eq(1), .selections li span:eq(1)').click(function ()   { self.step(1); });
	$$.find('.bar a.three, .group .title:eq(2), .selections li span:eq(2)').click(function () { self.step(2); });

	// add click events for switching views
	$$.find('.views li a').click(function () { byo.angle($(this).attr('class')); });

	// set up default widths
	$$.find('.group .panel').css('width',      this.d.panel.normal);
	$$.find('.group:last .panel').css('width', this.d.panel.final);

	// reset button
	$$.find('.reset').click(function () {
		self.set('case',    'black');
		self.set('orifice', 'pink-jack-ass');
		self.set('texture', 'original');
		self.step(0);
	});

	// add to cart buttons for byo -- go to review screen
	$$.find('.price a, .group a.final').click(function () {
		self.review = true;

		// get rid of all callouts
		$$.find('.callout, .next-callout').fadeOut(self.fade);
		self.has_interacted = false;

		// get rid of progress and buy/price buttons
		$$.find('.info .progress .bar, .info .price').fadeOut(self.fade);
		$$.find('.info').animate({
			height: '-=50px'
		}, self.fade);

		// change the selectors panel
		$$.find('.selectors').fadeOut(self.fade, function () {
			// generate upsells
			self.create_upsells(0, $$.find('.review .upsell:eq(0)'));
			self.create_upsells(1, $$.find('.review .upsell:eq(1)'));

			// update total
			$$.find('.review .price .numbers').html(self.total());

			$$.find('.review, .progress .done, .info .change').fadeIn(self.fade, function () {
				$$.css('height', self.o.byo.review);
			});
		});

		// switch angles
		self.angle('fortyfive');

		// add the product to cart in the bg
		self.add_byo();
	});

	// final add to cart & buy button
	$$.find('.total .buy-now').click(function () {
		/*
		self.add_byo(function () {
			window.location = '/shop.php?action=checkout';
		});
		*/
		window.location = '/shop.php?action=cart';
	});

	// set initial selections
	this.step(0);

	// launch callout to click cases
	setTimeout(function () {
		$('#byo .callout').show().animate({
			opacity: 1,
			top: '280px'
		}, 1500);
	}, 3000);
};


