/**
 * EmbeddedList.js - EmbeddedList widget.
 *
 * Copyright (c) 2009, 2010 Alikelist, Inc. All rights reserved.
 *
 * Embedded List is a widget to be embedded on external site (blogs, marketing sites, etc.). The widget is
 * designed to work with plain JavaScript and does not depend on any library.
 *
 * Developers:
 *     Tan Nhu - initial API and implementation
 */
(function(){
	var host, anchor, parent, script, addEvent, options, embeddedCode,
		TIMED_ROTATION_DURATION = 6000,
		bizIds, queueIds, showIds, timedIndex, bizInfo = {},
		listContent, startRemoving = false,
		mousein = false,
		showingCode = false,
		ie = ((navigator.appVersion.indexOf('MSIE') === -1) ? false : true),
		ie7 = ((navigator.appVersion.indexOf('MSIE 7.') === -1) ? false : true),
		ie8 = ((navigator.appVersion.indexOf('MSIE 8.') === -1) ? false : true);

	if ( !window.AL){
		AL = {};
	}

	/**
	 * Shortcut to addEventListener.
	 */
	function addEvent(obj, type, fn) {
		return obj.addEventListener ? obj.addEventListener(type, fn, false) : obj.attachEvent('on' + type, fn);
	}

	/**
	 * Shortcut to removeEventListener.
	 */
	function removeEvent(obj, type, fn) {
		return obj.removeEventListener ? obj.removeEventListener(type, fn, false) : obj.detachEvent('on' + type, fn);
	}

	/**
	 * Get height of a DOM object.
	 */
	function getHeight(obj){
		return ie ? obj.offsetHeight : obj.clientHeight;
	}

	/**
	 * Shortcut to document.getElementById.
	 */
	AL.$ = function(id){
		return document.getElementById(id);
	};

	/**
	 * Track events.
	 */
	AL.track = function(eventCode, bizId){
		new Image().src = host + '/embedded_list/log_event/ ' + eventCode + '/' + bizId;
	};

	/**
	 * Embed widget.
	 */
	AL.embedWidget = function(opts){
		options = opts;
		addEvent(window, 'load', function(){
			anchor = AL.$('alikelist-embedded-list-widget');
			host = anchor.src.split('/js/')[0];
			parent = anchor.parentNode;

			/*script = document.createElement('script');
			script.src = host + '/embedded_list/render/' + opts.listId
				+ '?borderColor=' + escape(opts.borderColor)
				+ '&width=' + escape(opts.width)
				+ '&height=' + escape(opts.height)
				+ '&showAvatar=' + escape(opts.showAvatar)
				+ '&showComments=' + escape(opts.showComments)
				+ '&name=' + escape(opts.name)
				+ '&showOffers=' + escape(opts.showOffers)
				+ '&random=' + escape(opts.random)
				+ '&numberShown=' + escape(opts.numberShown)
				+ '&timedRotation=' + escape(opts.timedRotation)
				+ '&borderColor=' + escape(opts.borderColor)
				+ '&listBackground=' + escape(opts.listBackground)
				+ '&headerBackground=' + escape(opts.headerBackground)
				+ '&listingNameColor=' + escape(opts.listingNameColor)
				+ '&descriptionColor=' + escape(opts.descriptionColor)
				+ '&nameColor=' + escape(opts.nameColor)
				+ '&listingLinksColor=' + escape(opts.listingLinksColor)
				+ '&commentsColor=' + escape(opts.commentsColor)
				+ '&locationColor=' + escape(opts.locationColor)
				+ '&designMode=' + (opts.designMode ? true : false);
			parent.appendChild(script);*/
			
			var div = document.createElement('div');
			
			div.innerHTML = '<p style="border: 1px solid green; background-color: yellow; padding: 5px;">We\'re sorry but that list has expired. Please <a href="' + host+ '" target="_blank">go to LikeList</a> to create a new list.</p>';
			parent.appendChild(div);
		});
	};

	/**
	 * Render widget.
	 */
	AL.renderWidget = function(content){
		var div = document.createElement('div'), html, h1, h2;
		div.innerHTML = content.replace('SINGLE_QUOTE', "'");
		parent.appendChild(div);
		parent.removeChild(script);

		// No scrolling when mouse in the list content
		addEvent(AL.$('al-embeded-list-content'), 'mouseover', function(){
			mousein = true;
		});
		addEvent(AL.$('al-embeded-list-content'), 'mouseout', function(){
			mousein = false;
		});

		// Setting up Timed rotation
		if (options.timedRotation === true){
			try {
				queueIds = AL.$('al-embedded-queue-biz-ids').innerHTML.split(',');
				if (queueIds && queueIds != '' && queueIds.length > 0){
					showIds = AL.$('al-embedded-show-biz-ids').innerHTML.split(',').reverse();
					bizIds = queueIds.concat(showIds);
					timedIndex = 0;
					listContent = AL.$('al-embeded-list-content');
					setTimeout(AL.doTimedRotation, TIMED_ROTATION_DURATION);
				}
			} catch (error){}
		} else {
			h1 = getHeight(AL.$('al-embeded-list-content'));
			h2 = h1 + getHeight(AL.$('al-footer'));
			AL.$('al-embedded-business-info').style.height = h1 + 'px';
			AL.$('al-embedded-show-code').style.height = h2 + 'px';
			AL.$('al-embedded-show-code-content').style.height = (h2 - 45 - (ie8 ? 10 : 0 )) + 'px';
		}
	};

	/**
	 * Timeout function for timed rotation.
	 */
	AL.doTimedRotation = function(){
		if (mousein) {
			return setTimeout(AL.doTimedRotation, TIMED_ROTATION_DURATION);
		}
		// Get Business Info
		if ( !bizInfo[bizIds[timedIndex]]){
			var script = document.createElement('script');
			script.src = host + '/embedded_list/rotation/' + bizIds[timedIndex] + '/' + options.listId;
			script.id = "al-render-timed-rotation-script";
			try {
				parent.removeChild(AL.$(script.id));
			} catch (error){}
			parent.appendChild(script);
		} else {
			AL.renderRotation(bizInfo[bizIds[timedIndex]]); // Render data
		}
	};

	/**
	 * Call-back function for /embedded_list/rotation.
	 */
	AL.queryRotation = function(data){
		bizInfo[bizIds[timedIndex]] = data;  // Cache data
		AL.renderRotation(data);             // Render data
	};

	/**
	 * Render rotation data.
	 */
	AL.renderRotation = function(data){
		// Pre-format data
		data.fullAddress = data.fullAddress ? data.fullAddress : '';
		data.phone = data.phone ? data.phone : '';
		data.website = data.website ? data.website : '';

		var	id = bizIds[timedIndex],
			tempId = 'al-embedded-list-entry-' + id,
			html2, entryId = 'al-embedded-list-entry-' + id,
			html = '<div class="al-embedded-list-entry" id="' + entryId+ '" PLACE_HOLDER>'
					+ '<a class="al-embedded-contact">'
						+ '<span class="al-hidden" id="al-embedded-contact-' + id + '-name">' + data.name + '</span>'
						+ '<span class="al-hidden" id="al-embedded-contact-' + id + '-url">' + data.url + '</span>'
						+ '<span class="al-hidden" id="al-embedded-contact-'  + id + '-address">' + data.fullAddress + '</span>'
						+ '<span class="al-hidden" id="al-embedded-contact-' + id + '-phone">' + data.phone + '</span>'
						+ '<span class="al-hidden" id="al-embedded-contact-' + id + '-website">' + data.website + '</span>'
					+ '</a>'
					+ '<div><strong class="al-listing-link-strong"><a id="al-embedded-contact-' + id + '" class="al-listing-link" onclick="AL.onContact(this, ' + id + ');">' + data.name + '</a></strong></div>';

		if (data.address && data.address != ''){
			html += '<div class="al-embedded-location">' + data.address + '</div>';
		}

		if (options.showComments === true && data.comment && data.comment != ''){
			html += '<div class="al-embedded-comment">' + data.comment + '</div>';
		}

		if (options.showOffers === true && data.promo && data.promo != ''){
			html += '<div class="al-embedded-promo">';
			html += '<div class="al-embedded-promo-box">';
			html += '<div class="al-embedded-promo-carrat"></div>';
			html += '<a href="' + data.promoUrl + '" target="_blank">' + data.promo + '</a>';
			html += '</div></div>';
		}

		html += '</div>';

		// Keep original html
		html2 = html.replace('PLACE_HOLDER', 'style="opacity: 0; filter=alpha(opacity=0);"');
		html = html.replace('PLACE_HOLDER', 'style="margin-top: 99999px;"');

		listContent.innerHTML = listContent.innerHTML + html;

		AL.animateRotation(ie7 ? document.getElementById(tempId).offsetHeight : document.getElementById(tempId).clientHeight, tempId, html2, entryId);
		listContent.removeChild(listContent.childNodes[listContent.childNodes.length - 1]);

		// Increase timedIndex
		timedIndex = (timedIndex < bizIds.length - 1) ? timedIndex + 1 : 0;

		// timedIndex reach the first showing item, start removing DOM
		if ( !startRemoving && timedIndex === queueIds.length){
			startRemoving = true;
		}
	};

	/**
	 * Animate rotation.
	 */
	AL.animateRotation = function(height, tempId, html2, entryId){
		var aniId = 'al-embedded-ani-holder',
			aniDiv, h = 1,
			entry,
			opacity = 0,
			html = '<div id="' + aniId + '" style="height: 1px; display: block;">&nbsp;</div>';

		function doOpacity(){
			opacity = ie ? opacity + 5 : opacity + 0.05;
			if ((ie && opacity > 105) || ( !ie && opacity > 1.05)){
				return;
			}
			if (ie){
				entry.style.filter = 'alpha(opacity=' + opacity + ')';
			} else {
				entry.style.opacity = opacity;
			}

			setTimeout(doOpacity, ie7 ? 10 : 20);
		}

		function doIncreaseHeight(){
			h = ie ? h + 2 : h + 1;
			aniDiv.style.height = h + 'px';
			if (h <= height){
				setTimeout(doIncreaseHeight, 2);
			} else {
				listContent.removeChild(listContent.childNodes[0]);
				listContent.innerHTML = html2 + listContent.innerHTML;
				if (startRemoving){
					listContent.removeChild(listContent.childNodes[listContent.childNodes.length - 1]);
				}
				setTimeout(AL.doTimedRotation, TIMED_ROTATION_DURATION);
				entry = AL.$(entryId);
				doOpacity();
			}
		}

		// Insert new animation entry at the top of list content
		listContent.innerHTML = html + listContent.innerHTML;

		// Do animation
		aniDiv = AL.$(aniId);
		doIncreaseHeight();
	};

	/**
	 * Contact button event handler.
	 */
	AL.onContact = function(th, listingId){
		var	id = th.id, e1, e,
			name = AL.$(id + "-name").innerHTML,
			address = AL.$(id + "-address").innerHTML,
			phone = AL.$(id + "-phone").innerHTML,
			url = AL.$(id + "-url").innerHTML,
			website = AL.$(id + "-website").innerHTML,
			tinyUrl = website.split('/');

		try {
			tinyUrl = (website.indexOf('://') != -1) ? tinyUrl[2] : tinyUrl[0];
			if (tinyUrl.length > 40 || AL.WIDTH < 210){
				tinyUrl = 'Website';
			}
		} catch (error){
			tinyUrl = (website && website.length > 0) ? 'Website' : '';
		}

		e1 = AL.$("al-embedded-business-info-name")
		e1.innerHTML = name;
		e1.href = url;

		// Track clicking to url event
		AL.onContact.track5 = AL.onContact.track5 || function(){
			removeEvent(e1, 'click', AL.onContact.track5);
			AL.track(5, listingId);
		};
		removeEvent(e1, 'click', AL.onContact.track5);
		addEvent(e1, 'click', AL.onContact.track5);

		AL.$("al-embedded-business-info-address").innerHTML = address;
		AL.$("al-embedded-business-info-phone").innerHTML = phone;
		e = AL.$("al-embedded-business-info-website");
		e.href = website;
		e.innerHTML = tinyUrl;

		// Track clicking to url event
		AL.onContact.trackFn = AL.onContact.trackFn || function(){
			removeEvent(e, 'click', AL.onContact.trackFn);
			AL.track(2, listingId);
		};
		removeEvent(e, 'click', AL.onContact.trackFn);
		addEvent(e, 'click', AL.onContact.trackFn);

		AL.$("al-embeded-list-content").style.display = "none";
		AL.$("al-see-more").style.visibility = "hidden";
		AL.$("al-footer").style.visibility = "hidden";

		AL.$("al-embedded-business-info").style.display = "block";
		AL.track(1, listingId);
	};

	/**
	 * Back link event handler.
	 */
	AL.onBack = function(){
		AL.$("al-embedded-business-info").style.display = "none";
		AL.$("al-embedded-show-code").style.display = "none";

		AL.$("al-embeded-list-content").style.display = "block";
		if (showingCode){
			AL.$("al-see-more").style.display = "block";
			AL.$("al-footer").style.display = "block";
		} else {
			AL.$("al-see-more").style.visibility = "visible";
			AL.$("al-footer").style.visibility = "visible";
		}
		showingCode = false;
	};

	/**
	 * Generate embedded code for "Embed this list" feature.
	 */
	AL.getCode = function(){
		var html;

		if (embeddedCode){
			return;
		}

		html = '<script id="alikelist-embedded-list-widget" src="' + host.replace('http:', '').replace('https:', '') + '/js/al/widgets/EmbeddedList.js"></script>\r\n';
		html += '<script type="text/javascript">\r\n';
		html += 'AL.embedWidget({\r\n';
		html += '   listId: ' + options.listId + ',\r\n';
		html += '   width: ' + options.width + ',\r\n';
		html += '   height: ' + options.height + ',\r\n';
		html += '   showAvatar: ' + options.showAvatar + ',\r\n';
		html += '   showComments: ' + options.showComments + ',\r\n';
		html += '   name: "' + options.name + '",\r\n';
		html += '   showOffers: ' + options.showOffers + ',\r\n';
		html += '   random: ' + options.random + ',\r\n';
		html += '   numberShown: ' + options.numberShown + ',\r\n';
		html += '   timedRotation: ' + options.timedRotation + ',\r\n';
		html += '   borderColor: "' + options.borderColor + '",\r\n';
		html += '   listBackground: "' + options.listBackground + '",\r\n';
		html += '   headerBackground: "' + options.headerBackground + '",\r\n';
		html += '   listingNameColor: "' + options.listingNameColor + '",\r\n';
		html += '   descriptionColor: "' + options.descriptionColor + '",\r\n';
		html += '   nameColor: "' + options.nameColor + '",\r\n';
		html += '   listingLinksColor: "' + options.listingLinksColor + '",\r\n';
		html += '   commentsColor: "' + options.commentsColor + '",\r\n';
		html += '   locationColor: "' + options.locationColor + '"\r\n';
		html += '});\r\n';
		html += '</script>';
		AL.$('al-embedded-show-code-content').value = html;

		embeddedCode = true;
	};

	/**
	 * Show embedded code.
	 */
	AL.showCode = function(){
		AL.$("al-embedded-business-info").style.display = "none";
		AL.$("al-embedded-show-code").style.display = "block";

		AL.$("al-embeded-list-content").style.display = "none";
		AL.$("al-see-more").style.display = "none";
		AL.$("al-footer").style.display = "none";

		AL.getCode();
		AL.$('al-embedded-show-code-content').focus();
		AL.$('al-embedded-show-code-content').select();
		showingCode = true;
	};

})();
