String.prototype.startsWith = function(str) {
	return (this.match("^"+str)==str);
};

String.prototype.endsWith = function(str) {
	return (this.match(str+"$")==str);
};

Number.prototype.formatNumber = function(decimalPlaces, decimalSeperator, thousandsSeperator){
    var n = this, decimalPlaces = isNaN(decimalPlaces = Math.abs(decimalPlaces)) ? 2 : decimalPlaces, decimalSeperator = decimalSeperator == undefined ? "." : decimalSeperator, thousandsSeperator = thousandsSeperator == undefined ? "," : thousandsSeperator, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(decimalPlaces)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
    return s + (j ? i.substr(0, j) + thousandsSeperator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousandsSeperator) + (decimalPlaces ? decimalSeperator + Math.abs(n - i).toFixed(decimalPlaces).slice(2) : "");
};

/*
 * Global HachLib Singleton variable accessible from anywhere in javascript
 * allows us to keep a sort of namespace through the singleton object.
 * All Hach functions and variables should be stored in the HachLib object.
 */
var HachLib = {};

// Inner Objects

HachLib.newsAndEvents = {};

// HachLib variables and functions

HachLib.isHeaderLoginFormOpen = false;
HachLib.defaultFadeSpeed = 300;
HachLib.defaultNumberOfOrderEntriesToAdd = 10;

HachLib.toggleHeaderLoginBox = function() {
    
    if (HachLib.isHeaderLoginFormOpen == true) {
        $("#headerLoginBox").fadeOut("fast");
        $("#headerLoginButton").attr("disabled",false);
        HachLib.isHeaderLoginFormOpen = false;
    } else {
        $("#headerLoginBox").fadeIn("fast");
        $("#headerLoginButton").attr("disabled",true);
        HachLib.isHeaderLoginFormOpen = true;
    }
    
};

HachLib.hideHeaderLoginBox = function() {
    
    if (HachLib.isHeaderLoginFormOpen) {
        $("#headerLoginBox").hide();
        $("#headerLoginButton").attr("disabled",false);
        HachLib.isHeaderLoginFormOpen = false;
    }
      
};

HachLib.generateErrorMessagesBlock = function(errorMessages) {
    
    var errors = '<div class="errorMessages">';
    
    for (var i = 0; i < errorMessages.length; i++) {
        
        errors += '<p>' + errorMessages[i] + '</p>';
        
    }
    
    errors += '</div>';
    
    return errors;
    
};

HachLib.scrollTo = function(selector) {
    
    if (typeof $.scrollTo == 'function' && $(selector).size() != 0) {
        $.scrollTo(selector);
    }
    
};

HachLib.initializeFieldDefault = function(selector, defaultValue) {
    
    $(selector).each(function() {

    	var element = $(this);
    	
    	if (element.val() == '' || element.val() == defaultValue) {
            element.css({ color: '#AAA', fontStyle: 'italic' });
            element.val(defaultValue);
        }
        
    });
    
    $(selector).live('blur', function() {
        
        element = $(this);
        
        if (element.val() == '' || element.val() == defaultValue) {
            element.css({ color: '#AAA', fontStyle: 'italic' });
            element.val(defaultValue);
        }
        
    });
    
    $(selector).live('focus', function() {
        
        element = $(this);
        
        if (element.val() == defaultValue) {
            element.css({ color: '#333', fontStyle: 'normal' });
            element.val('');
        }
        
    });
    
};

HachLib.clearFieldDefault = function(selector, defaultValue) {
	
	$(selector).each(function() {
		
		var element = $(this);
		
		if (element.val() == defaultValue) {
			element.val('');
		}
		
	});
	
};

HachLib.getCurrentDate = function() {

	var currentTime = new Date();
    var month = parseInt(currentTime.getMonth() + 1);
    var date = parseInt(currentTime.getDate());

    if (month < 10) {
        month = "0" + month;
    }
    
    if (date < 10) {
        date = "0" + date;
    }
    
    return currentTime.getFullYear() + '-' + month + '-' + date;
	
};

/**
 * Toggles product details in a table. The function can only be used on elements inside a table.
 */
HachLib.toggleProductRowDetails = function(selector) {
    
    if (!selector) {
        selector = "table a.productName";
    }
    
    var currentClass = "currentlyOpeningDetails";
    
    
    $(selector).die('click').live('click', function() {
        
        $(this).addClass(currentClass);
        
        var currentRow = $(this).closest('tr');
        
        $(selector).each(function() {
            
            var row = $(this).closest('tr');
            
            if ((row.find('div.description, div.thumb').css('display') != 'none') && (!$(this).hasClass(currentClass))) {
                row.find('div.description, div.thumb').slideUp(200);
            }
            
        });
        
        $(this).removeClass(currentClass);
        currentRow.find('div.description, div.thumb').slideToggle(200);
        
    });
    
};

HachLib.refreshShoppingCartHeader = function(itemCount, totalValue) {
    $("#shoppingCartItemCount").html( itemCount );
    $("#shoppingCartTotalValue").html( HachLib.formatMoney( totalValue ) );
};

HachLib.formatMoney = function( price ) {
    return "$" + parseFloat(price).formatNumber( 2, ".", "," );
};

HachLib.formatQuantity = function( quantity ) {
    return parseFloat(quantity).formatNumber( 0, ".", "," );
};

// Checks if the user's browser is IE6 or earlier.
HachLib.isIE6 = function() {
    return $.browser.msie && $.browser.version.substr(0,1) < 7;
};

HachLib.displayTextAreaCharCount = function(textareaSelector, counterSelector, limit) {
	
    $(textareaSelector).live('keyup', function() {
        var textareaValue = $(this).val();
        $(counterSelector).text(textareaValue.length);
        if (textareaValue.length > limit) {
            $(counterSelector).css({ color: "#C60C30", fontWeight: "bold" });
        } else {
            $(counterSelector).css({ color: "", fontWeight: "" });
        }
    }).keyup();
    
};

HachLib.webFlowSubmitForm = function(pFormIdentifier, pFormAction) {
	//To be PCI compliant, Credit card information cannot be saved.
	$("#mpg_cc_type").val( null );
	$("#mpg_cc_num").val( null );
	$("#mpg_cc_holder_name").val( null );
	$("#mpg_cc_exp_month").val( null );
	$("#mpg_cc_exp_year").val( null );
	$("#creditCardRefNumber").val( null );
     	
	$(pFormIdentifier).attr("action", pFormAction);
	$(pFormIdentifier).submit();
};

/**
 * Function that manages the values of the selects for choosing a credit card expiry date.
 * The function binds an event that ensures that a month that has already passed for 
 * the current year cannot be selected.
 */
HachLib.creditCardExpiryDateChoices = function(yearFieldSelector, monthFieldSelector) {
    
    var yearField = $(yearFieldSelector);
    var monthField = $(monthFieldSelector);
    
    var today = new Date();
    
    // Binds event to the year field that will change the month options depending on the year.
    yearField.change(function() {
        
        var options = '';
        var currentMonth = monthField.val();
        
        if (today.getFullYear() == $(this).val()) {
            
            // Get months that are not in the past only
            for (var i = parseInt(today.getMonth() + 1); i <= 12; i++) {
                
                var value = i;
                
                // Need to append a 0 if below 10
                if (i < 10) {
                    value = '0' + i;
                }
                
                if (i == currentMonth) { 
                    options += '<option value="' + value + '" selected="selected">' + value + '</option>';
                } else {
                    options += '<option value="' + value + '">' + value + '</option>';
                }
                
            }
            
        } else {
            
            // Get all months of a year
            for (var i = 1; i <= 12; i++) {
                
                var value = i;
                
                // Need to append a 0 if below 10
                if (i < 10) {
                    value = '0' + i;
                }
                
                if (i == currentMonth) { 
                    options += '<option value="' + value + '" selected="selected">' + value + '</option>';
                } else {
                    options += '<option value="' + value + '">' + value + '</option>';
                }
                
            }
            
        }
        
        monthField.find('option:gt(0)').remove();
        monthField.append(options);
        
    });
    
    if (today.getFullYear() == yearField.val()) {
        yearField.change();
    }
    
};

// Code we want to execute on DOM load of every page
$(document).ready(function() {
	
	if (navigator.userAgent.toLowerCase().match('chrome') ) {
		$("body").addClass("chrome");
	}

    // Code that should be executed upon every failed AJAX call
    $(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
    	
        // Create the container div at the top of the page if it does not exist.
        if ($('#main').find('#globalAjaxErrors').size() == 0) {
            $('#main').prepend('<div id="globalAjaxErrors" class="notificationMessage"></div>');
        }
        
        var styles = 'display: none;';
        var errorCount = $('#globalAjaxErrors div.ajaxError').size();
        
        // Add spacing if not the first error.
        if (errorCount > 0) {
            styles += ' margin: 10px 0 0;';
        }
        
        // If there are more than specified number, hide the rest with scrollbar to view.
        if (errorCount > 2) {
            $('#globalAjaxErrors').css({ 'height': $('#globalAjaxErrors').height(), 'overflow': 'auto' });
        }
        
        var errorHtml = '<div class="ajaxError failureWithIcon" style="' + styles + '">';
        errorHtml += '<span>Error: ' + jqXHR.status + ' / ' + thrownError + '</span>';
        errorHtml += '<span>URL: ' + ajaxSettings.url + '</span></div>';
        
        $('#globalAjaxErrors').append(errorHtml);
        $('#globalAjaxErrors').find('div.failureWithIcon:last').fadeIn(400);
        
        _trackEventGA('Ajax Error', jqXHR.status, ajaxSettings.url);
        
    });

    // Code that should be executed upon every successful AJAX call
    $(document).ajaxSend(function(event, jqXHR, ajaxOptions) {
    	_trackEventGA("Ajax", ajaxOptions.url);
    });
    
    // Sub Menus
    $("#mainNav li.root").hover(function() {
        var subNav = $(this).find("ul.subnav");
        if (subNav.css('display') == 'none') {
            subNav.slideDown('fast');
        }
    }, function() {
        var subNav = $(this).find("ul.subnav");
        if (subNav.css('display') == 'block') {
            subNav.slideUp('fast');
        }  
    });
    
    // Needed for the subnav menu. Add class on hover to apply styles instead of CSS :hover so it works with IE6.
    $('#mainNav li.root .subnav').hover(function() {
    	$(this).prev().addClass('subnavHeaderHover');
    	$(this).parent().next('li').addClass('clearSep');
    }, function() {
    	$(this).prev().removeClass('subnavHeaderHover');
    	$(this).parent().next('li').removeClass('clearSep');
    });
    
    $('#mainNav li.root').hover(function() {
    	$(this).next('li').addClass('clearSep');
    }, function() {
    	$(this).next('li').removeClass('clearSep');
    });   
    
    $('#headerLoginButton').attr('disabled', false).click(function() {

        $(this).attr('disabled', 'disabled');

        HachLib.toggleHeaderLoginBox();

        if ($('#headerLoginBox').css('display') != 'none') {
            $('#headerLoginFormUsername').focus();
        }

        return false;
        
    });

    $(document).mousedown(function() {
        HachLib.hideHeaderLoginBox();
    });

    $('#headerLoginBox').mousedown(function(e) {
        e.stopPropagation();
    });
    
    // External links open in new window while keeping HTML valid
    $('a[rel="external"]').live('click', function() {
    	$(this).attr('target', '_blank');
    });
    
	$("a.liveHelpLink").click(function() {
		javascript:window.open('https://server.iad.liveperson.net/hc/19743114/?cmd=file&file=visitorWantsToChat&site=19743114&imageUrl=https://server.iad.liveperson.net/hcp/Gallery/ChatButton-Gallery/English/General/2a/&referrer='+escape(document.location),'chat19743114','width=475,height=400,resizable=yes');
		return false;
	});
	
});
