function handleError(msg, url, line) {
    if (debug) {
        errorMsg = 'Error: ' + msg + '\n';
        errorMsg += 'URL: ' + url + '\n';
        errorMsg += 'Line: ' + line + '\n\n';

        alert(errorMsg);
        return false;
    } else {
        return true;
    }
}

if (debug) {
    window.onerror = handleError;
}


// this is called then the page has loaded
$(document).ready(function()
{
    /**
    * Initialise the 'set location' dialog box
    */
    $('#my_location').dialog(
        {
            autoOpen: false,
            title: 'Please enter your post code',
            modal: true,
            resizable: false,
            overlay: { opacity: 0.2, background: 'black'},
            open: function(ev, ui) {
                openDialog($(this));
            },
            close: function(ev, ui) {
            }
        }
    );

    /**
    * Initialise the 'login' dialog box
    */
    $('#login').dialog(
        {
            autoOpen: false,
            title: 'Login',
            modal: true,
            resizable: false,
            width: 400,
            overlay: { opacity: 0.2, background: 'black'},
            open: function(ev, ui) {
                openDialog($(this));
            },
            close: function(ev, ui) {
                location.reload();
            }
        }
    );
    /**
    * Initialise the 'register' dialog box
    */
    $('#register').dialog(
        {
            autoOpen: false,
            title: 'Register',
            modal: true,
            resizable: false,
            width: 400,
            overlay: { opacity: 0.2, background: 'black'},
            open: function(ev, ui) {
                openDialog($(this));
            },
            close: function(ev, ui) {
            }
        }
    );
    /**
    * Initialise the 'make homepage' dialog box
    */
    $('#sethomepage').dialog(
        {
            autoOpen: false,
            title: 'Make this your homepage',
            modal: true,
            resizable: false,
            width: 400,
            overlay: { opacity: 0.2, background: 'black'},
            open: function(ev, ui) {
                openDialog($(this));
            },
            close: function(ev, ui) {
                //
            }
        }
    );

    // call pageRefresh to load user preferences
    refreshPage();


}) ;
// end of $(document).ready


// generic function for showing popup dialog boxes
function showDialog(id)
{

    //if string passed, assume it refers to an ID. convert to node.
    var selector = (typeof id == "string" ? '#' : null)+id;
    selector = selector.replace('##', '#'); //fudge

    // first clear the .result panel of any old messages
    $(selector).children('.result').html('');

    // show the dialog
    $(selector).dialog('open');
    $(selector).show();
    return false;
}



// reflect changes saved by the user, name/theme
function refreshPage()
{
     // load the CSS theme
    var theme = $.cookie('durex[theme]');
    changeTheme(theme);

    return true;
}

// used when the user saves their postcode
function ajaxSetLocation(id,postcode)
{
    // check for null
    if (postcode == null || postcode == '')
    {
        $(id + ' .result').html('Please enter a postcode.');
        return false;
    }

    // check postcode format
    if (postcode.indexOf(' ') == -1)
    {
        postcodeEnd = postcode.substr(postcode.length-3, 3);
        postcodeStart = postcode.substr(0, postcode.length-3);
        postcode = postcodeStart + ' ' + postcodeEnd;
    }

    if (!/[A-Za-z]{1,1}[A-Za-z0-9]{1,3}[ ][0-9][A-Za-z]{2,2}/.test(postcode))
    {
        $(id + ' .result').html('This is not a valid post code.');
        return false;
    }

    $(id + ' .result').html("<img src='" + pathMod + "imgs/loading.gif'> Please wait...");

    // send an AJAX request to set_location.php, send a random number to prevent caching
    var url = pathMod + "customise_page.php";
    var script = true;
    $.getJSON(url, { postcode: postcode, rand: Math.random(), script : script }, function(data){
        // specifiy a callback function
        ajaxDefaultCallBack(id, data, 'default');
        refreshHomePage(); // added by Tony 7/8/09
    });
    return false;
}

// called by the 'login' dialog
function ajaxLogin (id, email, password)
{
    $(id + ' .result').html("<img src='" + pathMod + "imgs/loading.gif'> Please wait...");

    var url = pathMod + "login.php";
    var script = true;
    $.getJSON(url, { login_email: email, login_password : password, rand: Math.random(), script : script }, function(data){
        ajaxDefaultCallBack(id, data, 'default');
    });
    return false;
}

// called by the 'register' dialog.
function ajaxRegister (id, title, forename, surname, jobtitle, pct, address, towncity, county, postcode, name, email, password, agree, opt)
{
    $(id + ' .result').html("<img src='" + pathMod + "imgs/loading.gif'> Please wait...");

    if (!agree) {
        $(id + ' .result').html('You must agree to the <a href="' + pathMod + 'terms_and_conditions.php">Terms</a> and <a href="' + pathMod + 'privacy_policy.php">Privacy Policy</a>.');
        return false;
    }

    if (opt) opt = 1; else opt = 0;

    if (title == "0") {
        $(id + ' .result').html('You must select a title, please try again.');
        return false;
    }

    if (forename == "") {
        $(id + ' .result').html('Invalid forename, please try again.');
        return false;
    }

    if (surname == "") {
        $(id + ' .result').html('Invalid surname, please try again.');
        return false;
    }

    if (name == "") {
        $(id + ' .result').html('Invalid screen name, please try again.');
        return false;
    }

    if (!isEmail(email)) {
        $(id + ' .result').html('Invalid email address, please try again.');
        return false;
    }

    // NOTE isPassword returns -1 if valid, and returns a string error message if not valid
    var res = isPassword(password);
    if (res != -1) {
        $(id + ' .result').html(res);
        return false;
    }

    // register the user
    var script = true;
    var url = pathMod + "register.php";
    $.getJSON(url, { script: script, reg_title: title, reg_forename: forename, reg_surname: surname, reg_jobtitle: jobtitle, reg_pct: pct, reg_address: address, reg_towncity: towncity, reg_county: county, reg_postcode: postcode, reg_name : name, reg_email: email, reg_password: password, reg_agree: agree, reg_opt: opt, rand: Math.random() }, function(data){
        ajaxDefaultCallBack(id, data, 'default');
    });
    return false;
}

function addToFavorites() {
    if (window.sidebar) // Firefox - this has to be the first gate else it doesn't happen
        window.sidebar.addPanel("DurexHCP.co.uk", "http://www.durexhcp.co.uk","");
    else if (window.external) //IE
        window.external.AddFavorite("http://www.durexhcp.co.uk","DurexHCP.co.uk")
    else //else just describe what to do
        alert("Sorry - either you have JavaScript disabled in your browser or your browser does not support adding bookmarks through JavaScript.\n\nYou can usually bookmark a page by pressing CTRL+D. If that doesn't work, locate the 'bookmarks or 'favourites' menu in your browser, then select 'bookmark page' or similar.");
}

// generic callback frunction to inform the user of the AJAX result
function ajaxDefaultCallBack(id, data, behaviour, url)
{
    // find DIV.result and show the JSON result of the AJAX call
    if (!data['success'])
    {
        // this is the default behavior for an erro
        $(id).find('.result').html(data['general_message']);
    }
    else if (!behaviour || behaviour == 'default')
    {
        // this is the default behavior for success
        $(id + ' form').slideUp();
        $(id).find('.result').html(data['general_message']);
        refreshPage();
    }
    else if (behaviour == 'autoclose')
    {
        $(id).find('.result').html('');
        $(id + ' form').slideUp();
        $(id).dialog('close');
        refreshPage();
    }
    else if (behaviour == 'passive')
    {
        $(id).find('.result').html('');
        refreshPage();
    }
    else if (behaviour == 'redirect')
    {
        if (url == null)
        {
            url = './';
        }
        $(id).find('.result').html('');
        location.load(url);
    }
}

// change page theme
changeTheme.defaultStyle = "blue";
function changeTheme(style)
{
    if (style == null || style == '') style = arguments.callee.defaultStyle;
    switch (style) {
        case "green":
        case "pink":
        case "blue":
        case "cyan":
            var css = pathMod + 'css/myTheme/'+style+'.css';
            document.getElementById('css_myTheme').href = css;
            break;
        case null: return;
    }
}

/**
*   called when a dialog opens to make sure the FORM element is visible - each FORM is
*   hidden after use by ajaxDefaultCallBack()
*/
function openDialog(diag)
{
    diag.children('form').show();
}

/**
*   END OF jQUERY
*
*
*
*
*
*
*/










function startAjax() { //appropriate to browser being used
    var xmlHttpObj;
    if (window.XMLHttpRequest)
    xmlHttpObj = new XMLHttpRequest();
    else {
        try { xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP"); }
        catch (e) {
            try { xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP"); }
            catch (e) { xmlHttpObj = false; }
        }
    }
    return xmlHttpObj;
}















/**
*   BEGIN UTILITY FUNCTIONS
*
*
*
*
*
*
*
*
*/


/**
*   Search a string and convert encoded words such as '{:xeS:}ual' to 'Sexual'
*/
function decodeStopWords(code)
{
    var re = new RegExp(/({:([^:]+):})/gi);

    var arCodes = code.match(re);

    if (debug)
    {
        return code.replace(re, RegExp.$1 + '={' + RegExp.$2.split('').reverse().join('') + '}');
    }
    return code.replace(re, RegExp.$2.split('').reverse().join(''));
}

/**
* Validate a password.
*
* ****** RETURNS -1 IF VALID ********
*
* Returns error message if not valid.
*
* @param string password
* @return bool valid
*/
function isPassword(password)
{
    isValid = true;
    msg = '';
    if (!password) {
        isValid = false;
        msg = 'Please enter a password';
    }
    else if (password.length < 8)
    {
        isValid = false;
        msg = 'Your password must be at least 8 characters long.';
    }
    else if (password.length > 15)
    {
        isValid = false;
        msg = 'Your cannot be longer than 15 characters.';
    }
    else if (!password.match(/[A-Za-z]+/))
    {
        isValid = false;
        msg = 'Password must contain at least one letter.';
    }
    else if (!password.match(/[0-9]+/))
    {
        isValid = false;
        msg = 'Your password needs to contain at least one number.';
    }

    if (isValid)
    {
        return -1;
    } else {
        return msg;
    }
}

/**
* Validate an email address.
*
* Provide email address (raw input) Returns true if the email address has the email
* address format.
*
* @param string email
* @return bool valid
*/
function isEmail(email)
{
   isValid = true;
   atIndex = email.indexOf("@");
   if (!atIndex)
   {
      isValid = false;
   }
   else
   {
       domain = email.substring(atIndex+1);
      local = email.substring(0, atIndex);
      localLen = local.length;
      domainLen = domain.length;
      if (localLen < 1 || localLen > 64)
      {
         // local part length exceeded
         isValid = false;
      }
      else if (domainLen < 1 || domainLen > 255)
      {
         // domain part length exceeded
         isValid = false;
      }
      else if (local[0] == '.' || local[localLen-1] == '.')
      {
         // local part starts or ends with '.'
         isValid = false;
      }
      else if (local.match(/\.\./))
      {
          // local part has two consecutive dots
         isValid = false;
      }
      else if (!domain.match(/^[A-Za-z0-9\\-\\.]+/))
      {
         // character not valid in domain part
         isValid = false;
      }
      else if (domain.match(/\.\./))
      {
         // domain part has two consecutive dots
         isValid = false;
      }
      else if
( !(local.replace("\\","")).match(/^(\\.|[A-Za-z0-9!#%&`_=\\/\'*+?^{}|~.-])+/) )
      {
         // character not valid in local part unless
         // local part is quoted
         if (!(local.replace("\\","")).match(/^"(\\"|[^"])+"/))
         {
            isValid = false;
         }
      }
    }
   return isValid;
}

function urlencode(plaintext)
{
    if(plaintext == null || plaintext == '') {
        return '';
    }
    // The Javascript escape and unescape functions do not correspond
    // with what browsers actually do...
    var SAFECHARS = "0123456789" +                    // Numeric
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +    // Alphabetic
                    "abcdefghijklmnopqrstuvwxyz" +
                    "-_.!~*'()";                    // RFC2396 Mark characters
    var HEX = "0123456789ABCDEF";

    var encoded = "";
    for (var i = 0; i < plaintext.length; i++ ) {
        var ch = plaintext.charAt(i);
        if (ch == " ") {
            encoded += "+";                // x-www-urlencoded, rather than %20
        } else if (SAFECHARS.indexOf(ch) != -1) {
            encoded += ch;
        } else {
            var charCode = ch.charCodeAt(0);
            if (charCode > 255) {
                encoded += "+";
            } else {
                encoded += "%";
                encoded += HEX.charAt((charCode >> 4) & 0xF);
                encoded += HEX.charAt(charCode & 0xF);
            }
        }
    }

    return encoded;
};

function urldecode(encoded)
{
    if(encoded == null || encoded == '') {
        return '';
    }
    // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef";
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
       if (ch == "+") {
           plaintext += " ";
           i++;
       } else if (ch == "%") {
            if (i < (encoded.length-2)
                    && HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
                    && HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
                plaintext += unescape( encoded.substring(i,3) );
                i += 3;
            } else {
                plaintext += "%[ERROR]";
                i++;
            }
        } else {
           plaintext += ch;
           i++;
        }
    } // while
   return plaintext;
};

// Mouse events for SHARE button to validate page
function shareBtn()
{
    var div = document.getElementById("shareBtn");
    div.onmouseover = function() { return addthis_open(this, '', '[URL]', '[TITLE]') };
    div.onmouseout = function() { addthis_close() };
};

function shareBtn2()
{
    try {
        var div = document.getElementById("shareBtn2");
        div.onmouseover = function() { return addthis_open(this, '', '[URL]', '[TITLE]') };
        div.onmouseout = function() { addthis_close() };
    } catch(e) {}
};


// check for IE
function isIE()
{
    return /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent);
}

// clear form fields onclick (pass it an Object of id names and default values)
function clearFieldsOnFocus (fields)
{
    // drop out if code is unsupported
    if ( ! document.getElementsByTagName) return;

    for (var i in fields)
    {
        var fieldToClear = document.getElementById(i);

        fieldToClear.defaultValue = fields[i]; // store default val

        fieldToClear.onfocus = function ()
        {
            if (this.value == this.defaultValue)
            {
                this.value = '';
            }
        }
    }
}

//called by all printable version requests except condom selector (which has its own complicated dom>iframe>pop-up thing due to nature of printed content vs. what's displaying
function printableVersion(elementIdContainingContentToPrint) {
    if (elementIdContainingContentToPrint) {
        var joiner = location.href.indexOf("?") == -1 ? "?" : "&";
        printableWin = window.open(location.href+joiner+"doPrintableVersionOfContentInElementId="+elementIdContainingContentToPrint, "printableListWin", "width=650,height=650,scrollbars=1,dependent=0");
    }
}


//convert forms to ajax

$.prototype.ajaxifyForm = function(callback) {

    /*
     * submits form (as a jQuery selector, on which this method runs) via ajax, not normal form submit
     * method and URL are read from form's method and action attrs respectively
     * callback = callback func
     */

     $(this).submit(function(evt) {

         //stop normal submit
         evt.preventDefault();

         //prep
         var ac = arguments.callee;
         var pairs = [];
         var action = $(this).attr('action');
         var method = $(this).attr('method').toUpperCase() || 'POST'; //post assumed if not set
         var after = function() { var response = eval("("+request.responseText+")"); timeline.alert(response.text, response.type); }

         //die if no action set
         if (!action) { alert("Could not ajaxify form - no action set!"); return false; }

        //otherwise, traverse form and build a string of var/value pairings by reading its fields. If field has no name, ID is read; if no ID, field is excluded.
        $(this).children('input, textarea, select').each(function() {
            var type = $(this).attr('type').toLowerCase();
            if (type != 'submit' && type != 'clear')
                pairs.push(($(this).attr('id') || $(this).attr('name'))+"="+$(this).val());
        });
        pairs = pairs.join("&");

        //go
        var gateway = startAjax();
        if (!gateway)
                return;
        else {

            gateway.open(method, method == 'POST' ? action : action += (action.indexOf('?') == -1 ? '?' : '&')+pairs, true);

            if (method == 'POST') {
                gateway.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                gateway.setRequestHeader("Content-length", pairs.length);
                gateway.setRequestHeader("Connection", "close");
            }

            gateway.onreadystatechange = ajaxDoCallBack;
            gateway.send(method == 'POST' ? pairs : null);

        }

        //when we have a successful response, do callback
        function ajaxDoCallBack() {
            if (gateway.readyState == 4 && gateway.status == 200)
                eval('callback(gateway.responseText)');
        }
     });

}

//lightbox-powered alert() replacement.
//msgText = message to display
//callback = optional callback that will be applied to click event of first <button> found. If not passed, and button exists, click will simply close alert.
//confirmNotAlert = optional callback that will be applied to first button found with float == right. Means dialog can act like confirm(), not alert(), with 2 buttons

jqAlert = function(msgText, callback, confirmNotAlert) {

    //add message
    $('#lightboxAlert').html(msgText);

    //add callback to first button if passed
    if (typeof callback == 'function') $($('#lightboxAlert button').get(0)).click(function() { eval('callback()'); });

    //confirm not alert?
    if (typeof confirmNotAlert == 'function')
        $('#lightboxAlert button').each(function() {
            if ($(this).css('float') == 'right') {
                $(this).click(function() { eval('confirmNotAlert()'); });
                return false;
            }
        });

    //off we go
    lightbox('lightboxAlert');
}