/*------------------------------------------------------------------------------
  Coded by Ian Thomas, 2004
  thomas@ccdc.cam.ac.uk
  ----------------------------------------------------------------------------*/

var DEBUG = false;


function popupWin(path, width, height, windowName, scroll)
{
    var scrollbars;
    
    if ( scroll == 'no' )
        scrollbars = 'no';
    else
        scrollbars = 'yes';
    
    var features = "";
    if ( width != null )
        features += "width=" + width + ",";
    if ( height != null )
        features += "height=" + height + ",";
    
    var popup = window.open(path,
                            windowName,
                            features + "menu=no, title=yes, resizable=yes, scrollbars=" + scrollbars);
    
    return popup;
}


function window_is_open(window_to_check)
{
    return ( window_to_check && window_to_check.open && ! window_to_check.closed );
}


function is_internet_explorer()
{
    if ( navigator.userAgent.indexOf('MSIE') != -1 )
        return true;
    else
        return false;
}


function is_mac()
{
    if ( navigator.userAgent.indexOf('Macintosh') != -1 )
        return true;
    else
        return false;
}


function is_netscape()
{
    if ( navigator.userAgent.indexOf('Netscape') != -1 )
        return true;
    else
        return false;
}


function get_compatible_element(element_id)
{
    var element;
    
    if (document.getElementById)
    {
        // Standards Compliant code fork...
        element = document.getElementById(element_id);
    }
    else if (document.all)
    {
        // IE 4/5 code fork...
        element = document.all.element_id;
    }
    else if (document.layers)
    {
        // Nav 4.x code fork...
        element = document.layers[element_id];
    }
    else
    {
        // other browsers
        element = document.element_id;
    }
    
    return element;
}


function update_html_element(element_id, value)
{
    var element = get_compatible_element(element_id);
    
    element.value = value;
}


function update_html_inline(element_id, new_content)
{
    get_compatible_element(element_id).innerHTML = new_content;
}


// Function to toggle the 'disabled' attribute for a given element
function toggle_element_disabled(element_id)
{
    var element = get_compatible_element(element_id);
    
    var current_state = element.disabled;
    
    if ( current_state == true)
        element.disabled = false;
    else
        element.disabled = true;
}


function is_readonly(element)
{
    return element.readOnly;
}


// Function to toggle the 'readOnly' attribute for a given form element
function toggle_element_readonly(element_id)
{
    var element = get_compatible_element(element_id);
    
    var current_state = element.readOnly;
    
    if ( current_state == true)
        element.readOnly = false;
    else
        element.readOnly = true;
}


// Function to toggle the 'display' attribute for a given element
function toggle_element_display(element_id)
{
    var element       = get_compatible_element(element_id);
    var current_state = get_element_display(element_id);
    
    if ( current_state == 'none')
        element.style.display = '';
    else
        element.style.display = 'none';
}


// Function to toggle the 'visible' style attribute for a given element
function toggle_element_visibility(element_id)
{
    var element       = get_compatible_element(element_id);
    var current_state = get_element_visibility(element_id);
    
    if ( element.currentStyle )
    {
        if ( current_state == 'hidden' )
            element.style.visibility = "visible";
        else
            element.style.visibility = "hidden";
    }
    else if ( window.getComputedStyle )
    {
        if ( current_state == 'hidden' )
            element.style.setProperty("visibility", "visible", "");
        else
            element.style.setProperty("visibility", "hidden", "");
    }
    else
    {
        if ( current_state == 'hidden' )
            element.style.visibility = "visible";
        else
            element.style.visibility = "hidden";
    }
}


// Function to get the 'visible' style attribute for a given element
function get_element_visibility(element_id)
{
    var element = get_compatible_element(element_id);
    var current_state;
    
    if ( element.currentStyle )
    {
        current_state = element.currentStyle['visibility'];
    }
    else if ( window.getComputedStyle )
    {
        var element_style = window.getComputedStyle(element, null);
        current_state = element_style.getPropertyValue('visibility');
    }
    else
    {
        current_state = element.style.visibility;
    }
    
    return current_state;
}


function element_is_visible(element_id)
{
    return ( get_element_visibility(element_id) != 'hidden' );
}


// Function to get the 'display' style attribute for a given element
function get_element_display(element_id)
{
    var element = get_compatible_element(element_id);
    var current_state;
    
    if ( is_internet_explorer() && element.currentStyle )
    {
        current_state = element.currentStyle['display'];
    }
    else if ( window.getComputedStyle )
    {
        var element_style = window.getComputedStyle(element, null);
        current_state = element_style.getPropertyValue('display');
    }
    else
    {
        current_state = element.style.display;
    }
    
    return current_state;
}


function count_form_elements(form_id)
{
    var form_element, count;
    
    form_element = get_compatible_element(form_id);
    
    if ( form_element.elements.length )
        count = form_element.elements.length;
    else
        count = 0;
    
    if ( DEBUG )
        alert('count_form_elements - ' + count);
    
    return count;
}


function set_browser_status(status_message)
{
    window.defaultStatus = status_message;
    window.status = status_message;
}


function set_checkbox_state(checkbox, state)
{
    if ( checkbox )
        checkbox.checked = state;
}


function is_checked(checkbox)
{
    if ( is_mac() )
    {
        var current_state;
        
        if ( checkbox.checked )
            current_state = true;
        else
            current_state = false;
        
        if ( DEBUG )
            alert('is_checked - ' + checkbox.name + ' is ' + current_state);
        
        return current_state;
    }
    else
    {
        return checkbox.checked;
    }
}


function check_java_support()
{
    var result =
    { 
        javaEnabled: false,
        version: ''
    };
    
    if ( typeof navigator != 'undefined' &&
         typeof navigator.javaEnabled != 'undefined' )
        result.javaEnabled = navigator.javaEnabled();
    else
        result.javaEnabled = 'unknown';
    
    if ( navigator.javaEnabled() &&
         typeof java != 'undefined')
        result.version = java.lang.System.getProperty("java.version");
    
    if ( result.javaEnabled != true )
    {
        alert('Your internet browser does not appear to support JAVA applets. Please ensure that you have correctly installed and configured the appropriate JAVA Runtime Environment (JRE) for your platform.');
    }
}


function enter_key_pressed(e)
{
    var keycode;
    
    if (window.event)
        keycode = window.event.keyCode;
    else if (e)
        keycode = e.which;
    else
        return false;
    
    if ( keycode == 13 )
        return true;
    else
        return false;
}


function submit_via_enter_key(my_field, e)
{
    if ( enter_key_pressed(e) )
    {
        my_field.form.submit();
        return false;
    }
    else
        return true;
}


// Cross-browser function that signals whether frames are currently being used
function frames_are_being_used()
{
    if ( top.frames.length != 0 || parent.frames.length != 0 || self != top || parent != self )
        return true;
    else
        return false;
}


// Function to extract the value of a given cookie (if set on the current browser).
function get_cookie_value(cookie_name)
{
    var all_cookies = document.cookie;
    
    if ( all_cookies == "" )
        return false;
    
    var pos = all_cookies.indexOf( cookie_name + "=" );
    
    if ( pos == -1 )
        return false;
    
    var start = pos + cookie_name.length + 1; // length of name plus equals sign
    var end   = all_cookies.indexOf(";", start);
    
    if ( end == -1 ) // there's no ';' at the end
        end = all_cookies.length;
    
    var value = all_cookies.substring(start, end);
    value = unescape(value);
    
    return value;
}


function store_multiple_name_value_pairs_in_cookie( cookie_name,
                                                    name_value_pairs_array,
                                                    expiry_date_obj )
{
    var cookie_string = "";
    
    for ( var element in name_value_pairs_array )
    {
        if ( name_value_pairs_array[element] == null )
            continue;
        
        cookie_string += element + ":" + name_value_pairs_array[element].toString() + "/";
    }
    
    document.cookie = cookie_name + "=" + escape(cookie_string) +
                      "; expires=" + expiry_date_obj.toGMTString();
}


function read_multiple_name_value_pairs_from_cookie(cookie_name)
{
    var the_cookie = get_cookie_value(cookie_name);
    var cookie_info = new Array();
    
    if ( the_cookie == false )
        return cookie_info;
    
    // break each name:value pair into an array
    var separated_values = the_cookie.split("/");
    
    // loop through the list of name:values and populate the associative array...
    var property_value = "";
    
    for ( var i = 0; i < separated_values.length; i++ )
    {
        property_value = separated_values[i];
        var broken_info = property_value.split(":");
        
        var the_property = broken_info[0];
        var the_value = broken_info[1];
        
        if ( the_property.length == 0 || the_value.length == 0 )
            continue;
        
        cookie_info[the_property] = the_value;
    }
    
    return cookie_info;
}


// Function that counts the number of decimal places in a supplied float.
function get_number_of_decimal_places(float_value)
{
    if ( isNaN(float_value) || float_value == "" || float_value == null )
        return false;
    else
    {
        // Must convert to string before beginning string manipulation...
        float_value = String(float_value);
        
        // If there's no decimal point (i.e. it's an integer) add one at the end...
        if ( float_value.indexOf('.') == -1 )
            float_value += ".";
        
        // Calculate the number of decimal places...
        decimal_text = float_value.substring( float_value.indexOf('.') + 1, float_value.length );
        
        return decimal_text.length;
    }
}


function add_page_to_bookmarks(url, title)
{
    if ( title == "" )
        title = url;
    
    if ( document.all && window.external )
        window.external.AddFavorite(url, title);
    else
        alert("Sorry - this browser does not support automatic bookmarks.");
}


function add_current_page_to_bookmarks()
{
    add_page_to_bookmarks(location.href, document.title);
}


function string_contains_spaces(string)
{
    if ( string.indexOf(" ") == -1 )
        return false;
    
    return true;
}


function string_is_alphanumeric(string)
{
    var pattern = /^[\w ]+$/;
    return ( pattern.test(string) );
}


function string_is_floating_point_number(string)
{
    var pattern = /^[\d\.]+$/;
    return ( pattern.test(string) );
}


function string_is_integer(string)
{
    var pattern = /^[\d]+$/;
    return ( pattern.test(string) );
}


function string_is_valid_email( string )
{     
    if ( string.length < 1 )
        return false;
    
    // JCC - some web-borrowed regexps for simple email form validation
    //
    var invalid = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/; // not valid
    var valid = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/; // valid
        
    return (!invalid.test(string) && valid.test(string));// if syntax is valid     
}

function warn_user_if_readonly(element)
{
    if ( is_readonly(element) )
        alert("Sorry - this field is read-only and cannot be changed.");
}


function select_option_with_value( select_element_id, option_value )
{
    var selector = get_compatible_element(select_element_id);
    
    if ( ! selector )
        return;
    
    for ( var i = 0; i < selector.options.length; ++i )
    {
        if ( selector.options[i].value === option_value )
        {
            selector.selectedIndex = i;
            return;
        }
    }
}

function get_selected_option_value( select_element_id )
{
    var selector = get_compatible_element(select_element_id);
    
    if ( ! selector )
        return null;
    
    return selector.options[selector.selectedIndex].value;
}

function find_current_absolute_position( obj )
{
    var curleft = curtop = 0;
    if ( obj.offsetParent )
    {
        curleft = obj.offsetLeft;
        curtop = obj.offsetTop;
        while ( obj = obj.offsetParent )
        {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        }
    }
    return [curleft, curtop];
}

function function_available( function_name )
{
    return ( eval("typeof " + function_name + " == 'function'") );
}

function addEvent(obj, evType, fn)
{
    if (obj.addEventListener)
    {
        obj.addEventListener(evType, fn, false);
        return true;
    }
    else if (obj.attachEvent)
    {
        var r = obj.attachEvent("on"+evType, fn);
        return r;
    }
    else
    {
        //alert("Event handler could not be attached.");
        return false;
    }
}

function removeEvent(obj, evType, fn)
{
    if (obj.removeEventListener)
    {
        obj.removeEventListener(evType, fn, false);
        return true;
    }
    else if (obj.detachEvent)
    {
        var r = obj.detachEvent("on"+evType, fn);
        return r;
    }
    else
    {
        //alert("Event handler could not be removed.");
        return false;
    }
}

/*!
 * \brief Helper function to check if a given form input element is 'defined'.
 *
 * For text-based element types, this checks if the input 'value' is non-empty.
 *
 * For checkboxes and radio buttons, this checks if the input is 'checked'.
 *
 * For select elements, this checks if something is selected.
 *
 * \param input the input element to check
 * \return boolean
 */
function form_input_is_defined( input )
{
    switch ( input.type )
    {
        case 'file':
        case 'hidden':
        case 'password':
        case 'text':
        case 'textarea':
            return ( input.value.length > 0 );
        
        case 'checkbox':
        case 'radio':
            return input.checked;
        
        case 'select-one':
        case 'select-multiple':
            return ( input.selectedIndex != -1 );
        
        default:
            return false;
    }
}

/*!
 * \brief Helper function to check if a given radio button group is 'defined'.
 *
 * Returns true if any button in the group is currently 'checked'.
 *
 * \param form_id the id of the form containing the radio buttons
 * \param radio_name the shared name of the radio button group
 * \return boolean
 */
function radio_button_group_is_defined( form_id, radio_name )
{
    var form = get_compatible_element(form_id);
    
    if ( ! form[radio_name] )
    {
        alert('Cannot find radio button group \'' + radio_name + '\' in form \'' + form_id + '\'.' );
        return false;
    }
    
    for ( i = 0; i < form[radio_name].length; ++i )
    {
        if ( form[radio_name][i].checked )
            return true;
    }
    
    return false;
}

function resize_iframe_height_to_fit_content( iframe )
{
    if ( ! iframe )
    {
        alert('Cannot resize iframe to fit its content - specified iframe is not valid.');
        return;
    }
    
    // find the height of the internal document...
    var height = iframe.contentWindow.document.body.scrollHeight;
    
    // alternative measures of height...
    // var height = iframe.document.body.scrollHeight;
    // var height = iframe.document.body.offsetHeight;
    
    height += 20;
    
    // change the height of the iframe to fit the content...
    iframe.height = height;
}

function is_applet_ready( applet )
{
    if ( ! applet )
        throw new Error("Cannot determine if specified applet is ready - not a valid applet.");
    
    if ( typeof(applet.isActive) == 'undefined' )
        throw new Error("Cannot determine if specified applet is ready - isActive() function is not defined.");
    
    return applet.isActive();
}

function run_when_applet_ready( applet_id, function_name_to_run, max_wait )
{
    if ( typeof run_when_applet_ready.elapsed_wait == 'undefined' )
        run_when_applet_ready.elapsed_wait = 0; // initialise on first call
    
    try
    {
        if ( is_applet_ready( get_compatible_element(applet_id) ) )
        {
            window[function_name_to_run]();
            return;
        }
    }
    catch(e)
    {
        //alert(e.message);
    }

    if ( run_when_applet_ready.elapsed_wait >= max_wait )
    {
        throw new Error("Cannot run specified function - applet is still not ready after maximum wait.");
    }
    
    var timeout = 200;
    run_when_applet_ready.elapsed_wait += timeout;
    setTimeout( 'run_when_applet_ready(\'' + applet_id + '\', \'' + function_name_to_run + '\', ' + max_wait + ')', timeout );
}


