/**
 * State | Description
 * -------------------
 * 0     | The request is not initialised
 * 1     | The request has been set up
 * 2     | The request has been sent
 * 3     | The request is in process
 * 4     | The request is complete
 */

var BASE_DOMAIN  = 'http://' + document.domain + '/';
var EMPTY_STRING = '';
var ONE_SPACE    = ' ';

var xmlHttp = null;

function getXMLHttp() {
    var request = null;
    try {
        // Firefox, Opera 8.0+, Safari
        request = new XMLHttpRequest();
    }
    catch (e) {
        // Internet Explorer
        try {
            request = new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch (e) {
            request = new ActiveXObject('Microsoft.XMLHTTP');
        }
    }

    return request;
}

/**
 * The xmlHttpStateChanged() function must be implemented in a separate *.js
 * file.
 */
function sendRequest(url, mimeType) {
    xmlHttp = getXMLHttp();

    if (xmlHttp == null) {
        alert('Your browser does not support AJAX!');
    }
    else {
        try {
            xmlHttp.overrideMimeType(mimeType);
        }
        catch (e) {
            // Not supported by IE7
        }
        xmlHttp.onreadystatechange = xmlHttpStateChanged;
        xmlHttp.open('get', url, true);
        xmlHttp.send(null);
    }

    return;
}

/**
 * Call from the onload event of the body tag to open bookmarked pages; the
 * loadBookmarkedProduct() function is declared and managed by any JavaScript
 * file related to a specific product page.
 */
function useBookmark() {
    var bookmarkName = getURLParam('bookmark');

    if (bookmarkName == null) {
        bookmarkName = EMPTY_STRING;
    }

    loadBookmarkedProduct(bookmarkName);
    
    return;
}

/**
 * Utility function to get a URL parameter value by name.  Supports lowercase
 * parameter names and values only.
 */
function getURLParam(paramName) {
    var paramValue = EMPTY_STRING;
    var docHref    = window.location.href.split('#')[0];

    if (docHref.indexOf('?') > -1) {
        var query      = docHref.substr(docHref.indexOf('?') + 1).toLowerCase();
        var paramPairs = query.split('&');

        for (var i = 0; i < paramPairs.length; i++) {

            if (paramPairs[i].indexOf(paramName.toLowerCase() + '=') > -1) {
                var paramPair = paramPairs[i].split('=');
                paramValue    = paramPair[1];
                break;
            }
        }
    }

    return unescape(paramValue);
}

/**
 * Use when embedding a document with its own DOCTYPE, or other unwanted head
 * tags.
 */
function cleanNestedDocument(docText) {
    var docTemp = docText;
    docTemp     = docTemp.replace(/<(body|BODY)[\s\n\r\w="]+>/, '<body>');
    docTemp     = docTemp.replace(/<\/(body|BODY)[\s\n\r\w="]+>/, '</body>');
    var indexBody      = docTemp.indexOf('<body>') + 6;
    var indexBodyClose = docTemp.indexOf('</body>');
    var cleanText      = docTemp.substring(indexBody, indexBodyClose);

    return cleanText;
}

/**
 * Creates and returns an XML tree document from the xmlHttp object's response
 * property.
 */
function getXmlTree() {
    var rawDoc = xmlHttp.responseText;
    var xmlDoc = xmlHttp.responseXML.documentElement;
            
    if (window.ActiveXObject) {
        xmlDoc       = new ActiveXObject('Microsoft.XMLDOM');
        xmlDoc.async = 'false';
        xmlDoc.loadXML(rawDoc);
    }
    else {
        var parser = new DOMParser();
        xmlDoc     = parser.parseFromString(rawDoc, 'text/xml');
    }

    return xmlDoc;
}
