/*
 * ------------------------------------------------------------------------------------------------------------
 *  THIS CODE IS NOT APPROVED FOR USE IN/ON ANY OTHER WEB SITE OR PRODUCT COMPONENT.
 *  Copyright (c) 2009 Backcountry.com.  All rights reserved.
 * ------------------------------------------------------------------------------------------------------------
 */
 
/**
 * ------------------------------------------------------------------------------------------------------------
 * Method to define a namespace
 * ------------------------------------------------------------------------------------------------------------
 */
var namespace = function(namespace) {
	var nameParts = namespace.split('.');
	var scope = window;
	for (var i = 0; i < nameParts.length; i++) {
		if (!scope[nameParts[i]]) {
			scope[nameParts[i]] = {};
		}
		scope = scope[nameParts[i]];
	}
};

/**
 * ------------------------------------------------------------------------------------------------------------
 * Define a new namespace to use for all utilitary methods
 * ------------------------------------------------------------------------------------------------------------
 */
 
namespace('BCNTRY.odat.tab.alerts.utils');


/**
 * ------------------------------------------------------------------------------------------------------------
 * Method to bind a function and its arguments so it can be used in different scopes
 * ------------------------------------------------------------------------------------------------------------
 */

BCNTRY.odat.tab.alerts.utils.bind = function(fn, obj, args) {
	return function() {
		var finalArgs = [];
		
		if (args) {
			for (var j = 0; j < args.length; j++) {
				finalArgs.push(args[j]);
			}
		}		
		if (arguments) {
			for (var i = 0; i < arguments.length; i++) {
				finalArgs.push(arguments[i]);
			}
		}
	
		return fn.apply(obj || window, finalArgs);
	};
};

/**
 * ------------------------------------------------------------------------------------------------------------
 * Define a new namespace for specific tab alerts functions
 * ------------------------------------------------------------------------------------------------------------
 */

namespace('BCNTRY.odat.tab.alerts');

/**
 * ------------------------------------------------------------------------------------------------------------ 
 *  							*** SOUNDMANAGER OBJECT DEFINITION ***
 * Statis object to define all the utils functions related to the sound for the tab alert like cookie 
 * management for instance.
 * IMPORTANT: This depends on the file soundmanager2.js. We added a validation inside this file
 * to check for Flash, if a newer version of this file is included, we need to add that validation again.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.SoundManager = {

	_isSoundSupported: true,
	_cookieName: BCNTRY.site.catalog + "TabAlertSoundEnabled", // create a unique name for each ODAT site.
	_cookieExpires: null,	
	_cookiePath: "/",
	_soundId: BCNTRY.site.catalog + "TabAlertSound",

	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to init the sound. This should be called by the soundManager on the onload event.
	 * ------------------------------------------------------------------------------------------------------------
	 */	
	initSound: function(soundUrl) {
		// Create sound and load it
		soundManager.createSound({
			id: this._soundId,
			url: soundUrl
		});
	},
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to init the utils. Basically it sets the cookie expiration date to 30 days after today and sets
	 * the sound on/off link depending on the cookie value.
	 * ------------------------------------------------------------------------------------------------------------
	 */	
	init: function(soundUrl, swfPath) {
		this._cookieExpires = 30;  //set it to expire 30 days ahead  
		
		// If this cookie has never been set, set it to disabled
		var enabled = this.getCookie(this._cookieName);	
		if (!enabled) {
			this.setCookie(this._cookieName, "0", this._cookieExpires, this._cookiePath);
		}
		
		// Check if the soundManager was successfully created (if Flash is installed)
		if (soundManager !== null) {
			// Disable sound debugMode
			soundManager.debugMode = false;	
			soundManager.consoleOnly = true;
	
			// Set the right path for the SWF files
			soundManager.url = swfPath;
			
			// Set soundManager onload function
			soundManager.onload = BCNTRY.odat.tab.alerts.utils.bind(this.initSound, this, [soundUrl]);
		
			// Oh no! No sound support. Maybe configure your app to ignore sound calls.
			// (SM2 calls will silently return false after this point.)
			soundManager.onerror = BCNTRY.odat.tab.alerts.utils.bind(this.soundNotSupported, this);

		} else {
			// Flash is not installed, configure app so ignored sound calls
			this.soundNotSupported();
		}
		
	},
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to configure the app so it ignore sound calls because sound is not supported.
	 * ------------------------------------------------------------------------------------------------------------
	 */		
	soundNotSupported: function() {
		// Sound is not supported
		this._isSoundSupported = false;
		
		// Set the cookie as false
		this.setCookie(this._cookieName, "0", this._cookieExpires, this._cookiePath);
	},
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to play the sound.
	 * ------------------------------------------------------------------------------------------------------------
	 */		
	play: function() {
		if (this.isEnabled() === true) {
			soundManager.play(this._soundId);
		} 
	},
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to set the cookie value. It uses the _setCookie function defined in ...
	 * @param {String} name The name of the cookie to be set.
	 * @param {Object} value The value of the cookie.
	 * @param {Number} expires The expire date of the cookie expressed in milliseconds.
	 * @param {String} path The path of the cookie
	 * ------------------------------------------------------------------------------------------------------------
	 */		
	setCookie: function(name, value, expires, path) {
		_setCookie(name, value, expires, path);
	},

	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to retrieve a cookie value. It uses the _readCookie function defined in ...
	 * @return {Object} The value of the cookie.
	 * ------------------------------------------------------------------------------------------------------------
	 */		
 	getCookie: function(name) {
		return _readCookie(name);
	},	

	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to enable/disable the sound by setting the cookie value depending on previous value.
	 * ------------------------------------------------------------------------------------------------------------
	 */		
	setEnabled: function() {
		// Only set the cookie and change the sound icon, if the sound is supported
		if (this._isSoundSupported === true) {
			// Read the cookie value
			var enabled = this.getCookie(this._cookieName);
			
			// If cookie is being set but it doesn't have a value yet, enable it.
			enabled = (enabled ? (enabled == "1" ? "0" : "1") : "1");
		
			// Set the cookie
			this.setCookie(this._cookieName, enabled, this._cookieExpires, this._cookiePath);
			
			// Update the sound icon with the right image
			this.setSoundOnOffLink();
		} 
	},

	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to check if the sound is enable or not.
	 * @return {Boolean} True if the sound is enabled, false otherwise.
	 * ------------------------------------------------------------------------------------------------------------
	 */	
	isEnabled: function() {
		return (this.getCookie(this._cookieName) == "1");
	},
 
 	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to set the text of the sound on/of link depending on the sound being enabled or not.
	 * ------------------------------------------------------------------------------------------------------------
	 */	
	setSoundOnOffLink: function() {
		if (this.isEnabled() === true) {
			document.getElementById("tabAlertSoundOnOff").src = "/images/" + BCNTRY.site.catalog + "/tabAlertSoundOn.gif";
		} else {
			document.getElementById("tabAlertSoundOnOff").src = "/images/" + BCNTRY.site.catalog + "/tabAlertSoundOff.gif";
		}
		
		// Set the sound link title to Sound
		if (this._isSoundSupported === true) {	
			document.getElementById("tabAlertSoundOnOffLink").title = "Sound";	
		} else {
			document.getElementById("tabAlertSoundOnOffLink").title = "No sound supported, you need to install Adobe Flash plugin on your browser!";	
		}
	}
	
}; 

// Init the sound manager to load the correspondent tab alert sound
BCNTRY.odat.tab.alerts.SoundManager.init(BCNTRY.site.tabAlertSoundUrl, "/docs/bin/swf/");

/**
 * ------------------------------------------------------------------------------------------------------------ 
 *  							*** TABALERTER OBJECT DEFINITION ***
 * ------------------------------------------------------------------------------------------------------------
 */
/**
 * ------------------------------------------------------------------------------------------------------------
 * Constructor of the Item object
 * @constructor:
 *
 * @param {String} title The title of the product
 * @param {String} price The regular price of the product.
 * @param {String} discount The discount that was applied to the product
 * 
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.Item = function(skuClass, title, price, discount) {
	this._skuClass = skuClass;
	this._title = title;
	this._price = "$" + price;
	this._discount = discount + "% off";	
};

/**
 * ------------------------------------------------------------------------------------------------------------
 * Constructor of the TabAlerter object
 * @constructor:
 *
 * @param {String} siteName The name of the ODAT site
 * @param {String} favIconUrl The URL of the original site Favicon
 * @param {String| greyFavIconUrl The URL of the site Favicon, but greyish. This is used to alternate the favicon.
 * @param {Object} item The current item object that is on the site right now
 * @param {Object} sound The sound object for the tab alert.
 * @param {Number} titleAlternateDelay The number of milliseconds we want to delay the title text when 
 * 					alternating
 * 
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter = function(siteName, favIconUrl, greyFavIconUrl, item, sound, titleAlternateDelay) {
	this._siteName = siteName;
	this._favIconUrl = favIconUrl;
	this._greyFavIconUrl = greyFavIconUrl;	
	this._item = item;
	this._sound = sound;
	this._titleAlternateDelay = titleAlternateDelay;
	
	this._isTabAlertEnabled = false;
	this._currentFavIcon = this._favIconUrl;
};


/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to set Omniture tracking data when the tab alerts stops
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.sendOmnitureStopEventTracking = function() {
	
	// Methods defined in SiteCatalystUtil.js
	ScTrackTabAlertStop();
	
	// Track when the user clicks to track which item is on the site
	ScTrackTabAlertClick(this._item._skuClass);
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to set Omniture tracking data when the tab alerts starts
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.sendOmnitureStartEventTracking = function() {
	
	var varValue = this._siteName + ": " + this._item._title + " - " + this._item._price + " - " + this._item._discount;
	
	// Method defined in SiteCatalystUtil.js
	ScTrackTabAlertStart(varValue);
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to enable the tab alert. Only if the tab alert is enabled can start running.
 * @param {Boolean} enable Enables or disables the tab alert
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.enableTabAlert = function(enable) {
	this._isTabAlertEnabled = enable;
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to determine if the tab alert is on or not.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.isTabAlertEnabled = function() {
	return this._isTabAlertEnabled;
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to play the sound if enabled.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.playSound = function() {
	try {
		this._sound.play();
	} catch(errors) {
		// This is a hack for IE, for some reason in IE, the method onload on the sound manager is not executed
		// yet the first time we want to play the sound, so we are setting this to play agan half a sec later.
		if (this.isTabAlertEnabled() === true) {
			setTimeout(BCNTRY.odat.tab.alerts.utils.bind(this.playSound, this), 500);
		}
		
	}
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to remove the favicon link from the document head if exists.
 *
 * This method was taken from Favicon.js - Change favicon dynamically [http://ajaxify.com/run/favicon].
 * Copyright (c) 2006 Michael Mahemoff. Only works in Firefox and Opera.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.removeFavIconLinkIfExists = function() {
  	var head = document.getElementsByTagName("head")[0];	
  	var link = document.getElementById("odatFavicon");
  	if (link && link.type == "image/vnd.microsoft.icon" && link.rel == "shortcut icon") {
  		head.removeChild(link);
  	}
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function add a new link for the new icon to the head document.
 *
 * @param {String} iconUrl The url to the new icon.
 * 
 * This method was taken from Favicon.js - Change favicon dynamically [http://ajaxify.com/run/favicon].
 * Copyright (c) 2006 Michael Mahemoff. Only works in Firefox and Opera.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.addFavIconLink = function(iconURL) {
    if (YAHOO.env.ua.gecko > 0) {
        var link = document.createElement("link");
        link.type = "image/vnd.microsoft.icon";
        link.rel = "shortcut icon";
        link.id = "odatFavicon";
        link.href = iconURL;
        
        this.removeFavIconLinkIfExists();
        var head = document.getElementsByTagName("head")[0];
        head.appendChild(link);
    }
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to determine the next favicon to be displayed. It is calculated depending on the current favicon.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.nextFavIcon = function() {
  	return (this._currentFavIcon == this._favIconUrl) ? this._greyFavIconUrl : this._favIconUrl;
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to animate the tab by changing the document title and the favicon.
 *
 * @param {String} newTitle The new title that is going to be set in the document title.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.animateTab = function(newTitle) {
	if (this.isTabAlertEnabled() === true) {
		document.title = newTitle;
		
        // Favicon refreshing only works for FF
        this._currentFavIcon = this.nextFavIcon();
        this.addFavIconLink(this._currentFavIcon);
	}
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to set the document title when there is a new product. It alternates the text between the site name
 * the product title and the product discount, using a delayed defined by _titleAlternateDelay
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.alertTab = function() {

	if (this.isTabAlertEnabled() === true) {

		// First set the site name
		this.animateTab(this._siteName);
		
		// 3 seconds later, set the product title
		setTimeout(BCNTRY.odat.tab.alerts.utils.bind(this.animateTab, this,  [this._item._title]), this._titleAlternateDelay);
		
		// 6 seconds later, set the product discount
		setTimeout(BCNTRY.odat.tab.alerts.utils.bind(this.animateTab, this, [this._item._discount]), (this._titleAlternateDelay * 2));	
	
		// If the tab alert is still on, alternate the text in the title again
		setTimeout(BCNTRY.odat.tab.alerts.utils.bind(this.alertTab, this), (this._titleAlternateDelay * 3));	
	}
};


/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to alert the tab. Right now, it will only call the function to change the title.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.start = function() {

    this.originalTitle = document.title;
    
	// Set global variable to true
	this.enableTabAlert(true);

	// Change the title
	this.alertTab();	
	
	// Set Omniture tracking event
	this.sendOmnitureStartEventTracking();

	// Play the tab alert sound if enabled
	this.playSound();		
	
};


/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to reset the document title to its original title.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.resetTab = function() {

	// Reset to default title
    document.title = this.originalTitle;
    
    // Only for FF
    // Reset the current favicon
    this._currentFavIcon = this._favIconUrl;
    // Create default favicon
    this.addFavIconLink(this._favIconUrl);
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 * Function to stop the tab alert and call the omniture tracking event.
 * ------------------------------------------------------------------------------------------------------------
 */
BCNTRY.odat.tab.alerts.TabAlerter.prototype.stop = function() {

	// reset the title to its original title
	this.resetTab();
	
	// Send Omniture event tracking
	this.sendOmnitureStopEventTracking();			
};

/**
 * ------------------------------------------------------------------------------------------------------------ 
 *  							*** TABALERTERMANAGER OBJECT DEFINITION ***
 *
 * Static object to manage everything related to the tab alert effects like starting the tab alert, stopping it
 * stop it if time out, play sound, change sound settings, etc.
 * ------------------------------------------------------------------------------------------------------------
 */ 
BCNTRY.odat.tab.alerts.TabAlertManager = {
	
	_tabAlerter: null,
  
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to timeout the tab alert. This function should not call the Omniture tracking event.
	 * ------------------------------------------------------------------------------------------------------------
	 */
	timeoutTabAlert: function() {

		if (this._tabAlerter !== null && typeof this._tabAlerter !== 'undefined') {
			if (this._tabAlerter.isTabAlertEnabled() === true) {
		
				// Disable the tab alerter
				this._tabAlerter.enableTabAlert(false);
	
				// Stop the tab alert, by reseting the title and the favicon
				this._tabAlerter.resetTab();
			}			
		}
			
	},

	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to reset the document title to the original one.
	 * ------------------------------------------------------------------------------------------------------------
	 */
	stopTabAlert: function(args) {
	
		if (this._tabAlerter !== null && typeof this._tabAlerter !== 'undefined') {
			if (this._tabAlerter.isTabAlertEnabled() === true) {
		
				// Disable the tab alerter
				this._tabAlerter.enableTabAlert(false);
			
				// Stop the tab alert
				this._tabAlerter.stop();
			}
		}
		return false;
	},
	
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to start the tab alert.
	 * Also, it sets the onfocus function to stop the alert when the user clicks on the tab.
	 *
	 * ------------------------------------------------------------------------------------------------------------
	 */
	startTabAlert: function() {
	    
		try {
					
            var item = new BCNTRY.odat.tab.alerts.Item(BCNTRY.page_data.skuClass, BCNTRY.page_data.productTitle, BCNTRY.page_data.price, BCNTRY.page_data.discount);
            
            // Create a new TabAlert object
            this._tabAlerter = new BCNTRY.odat.tab.alerts.TabAlerter(BCNTRY.site.name, BCNTRY.site.favicon, BCNTRY.site.faviconGrey, item, BCNTRY.odat.tab.alerts.SoundManager, 2000);

            // Start the tab alert
            this._tabAlerter.start();
            
            // Set timer to stop alert timeout time has passed
            setTimeout(BCNTRY.odat.tab.alerts.utils.bind(this.timeoutTabAlert, this), (BCNTRY.site.tabAlertTimeout * 1000));

        }
		catch(err) {
		}
	    return 0;
	},
	
	/**
	 * ------------------------------------------------------------------------------------------------------------ 
	 * Function to initialize the tab alert. It creates the TabAlert object and starts the animation only if the
	 * ODAT site was reloaded by Dynodat. 
	 * ------------------------------------------------------------------------------------------------------------
	 */
	initializeTabAlert: function() {
		
		BCNTRY.odat.tab.alerts.SoundManager.setSoundOnOffLink();
		
		// Check if the page was refreshed by Dynodat, not just by a user reload
		var hasOdatRefreshed = _readCookie('odat_has_refreshed') || '';
	
		// Only start the tab alert if the refresh was caused by Dynodat
		if (hasOdatRefreshed !== null && hasOdatRefreshed !== "") {
		     this.startTabAlert();
		}
	}

};
	

/**
 * ------------------------------------------------------------------------------------------------------------
 * Set the function to catch event when user comes back to the tab, so we can stop the tab alert.
 * ------------------------------------------------------------------------------------------------------------
 */
if (YAHOO.env.ua.ie > 0)  {// Use onfocusin for IE
    YAHOO.util.Event.addListener(document, "focusin", function(ev){YAHOO.util.Event.stopEvent(ev);this.stopTabAlert();}, BCNTRY.odat.tab.alerts.TabAlertManager, true); 
}
else {
    YAHOO.util.Event.addListener(document, "focus", function(ev){YAHOO.util.Event.stopEvent(ev);this.stopTabAlert();}, BCNTRY.odat.tab.alerts.TabAlertManager, true);
}	

