function GetSelectedText() {
    var start;
    var end;
    var string;
    if ( window.getSelection ) {                                          // mozilla browsers
        var selectionObject = window.getSelection();
        var rangeObject = getRangeObject( selectionObject );              // takes care of Safari quirk
        start = rangeObject.startOffset+1;
        end   = rangeObject.endOffset;

        str = selectionObject;

    }
    else if ( document.selection && document.selection.createRange ) {    // IE browsers
        var selectionObject = document.selection;
        var rangeObject = selectionObject.createRange();

        // I'm going to use a bookmark object to get the selection position.
        // The bookmark object stores current position of the insertion point,
        //  but with respect to the document string, not the element string.
        // So we need to set a base location...
        var baseLocationText = 'PDB file:';
        var baseLocationOffset = 55;             // this must change with baseLocationText
        var docRangeObject = document.body.createTextRange();
        if ( !docRangeObject.findText( baseLocationText ) ) {
            alert( "could not find " + baseLocationText );
        }
        else {
            docBookmark = docRangeObject.getBookmark();
            refStart = docBookmark.charCodeAt(2) - 1 - docBookmark.charCodeAt(0);
        }
        var selectionLength = rangeObject.text.length;
        bookmark = rangeObject.getBookmark();
        start = bookmark.charCodeAt(2) - 1 - bookmark.charCodeAt(0) - ( refStart + baseLocationOffset );
        end   = start + selectionLength - 1;

        str = rangeObject.text;

    }
    else {
        str = "Sorry, this is not possible with your browser.";
    }

    // display the selected string
//    document.jmolForm.showSelectedText.value = str;

    // account for various idiosynchracies in the pdb file numbering
    start = AdjustSelectionOffsetAccordingToProteinAlignment( 'gp120', start );
    end   = AdjustSelectionOffsetAccordingToProteinAlignment( 'gp120',   end );

    // highlight residues corresponding to selection in Jmol window
//    alert ( "calling jmolHighlight with positions " + start + "-" + end );
    jmolHighlight( start + "-" + end );
}

/* This function is only needed to account for some Safari weirdness */
function getRangeObject( selectionObject ) {
    if ( selectionObject.getRangeAt )                                     // most mozilla browsers
        return selectionObject.getRangeAt( 0 );
    else {                                                                // Safari!
        var rangeObject = document.createRange();
        rangeObject.setStart( selectionObject.anchorNode,selectionObject.anchorOffset );
        rangeObject.setEnd( selectionObject.focusNode,selectionObject.focusOffset );
        return rangeObject;
    }
}

function AdjustSelectionOffsetAccordingToProteinAlignment( protein, offset ) {

    // if ( protein == 'gp120' ), then do this
    if ( offset == 323 ) { offset = "322^A"; } else if ( offset > 323 ) { offset--; }
    if ( offset == 463 || offset == 464 ) { exit; }
    if ( offset > 463 ) { offset = offset - 2; }

    return offset;
}

/*
  Takes a string like '230-242, 315' as an argument, and highlights the indicated residues
  in the Jmol display.  An optional second argument set to 'true' will leave any previously
  highlighted residues 'on'.  Default is to erase any previous highlighting.
  Detects the 'multiple selections persist' checkbox state and acts accordingly.
  jmolHighlight currently highlights by setting the (atoms in the) selected residues
  to 'spacefill 60%'.
  Also prints currently highlighted sequence numbers in 'currently highlighted' text box.
*/
function jmolHighlight( positions, persist ) {

    // detect whether 'persist' checkbox is selected
    if( document.jmolForm.persist.checked == true ) {
        persist = true;
    }

    // detect whether 'high contrast' checkbox is selected
    var contrast = '';
    if ( document.jmolForm.contrast.checked == true ) {
        contrast = true;
    }

    // script to 'highlight' indicated residues
    currentColorSchemeScript = ( document.jmolForm.colorScheme.value != 'select' )
                             ? jmolColorSchemeScriptFor( document.jmolForm.colorScheme.value )
                             : jmolColorSchemeScriptFor( 'temperature' );
                                // Need alternative in case no color scheme has been selected.
                                // Could eliminate this stuff by having labels and default values
                                // for the two style menus.
    contrastScript = ( contrast )
                   ? "color grey; "
                   : currentColorSchemeScript;
    var selectScript = contrastScript
                     + "select " + positions + "; "
                     + currentColorSchemeScript
                     + "spacefill 60%; select all;";

    // Needs work - high-contrast and persistent selection don't play nice together.
    // Should have what to do with 'select all' and what to do with 'highlight these'
    //  better separated.
    if ( persist ) {
        // concatenate new choices to those shown in the 'currently highlighted' box
        var commaSpace = "";
        if ( document.jmolForm.showPDBcoords.value ) {   // if it's not empty
            commaSpace = ", ";
        }
        document.jmolForm.showPDBcoords.value += commaSpace + positions;
    } else {
        // set script to erase previous highlights; show only new choices in 'currently highlighted' box
        currentStyle = document.jmolForm.displayStyle.value;
        displayStyleScript = 'wireframe 20; spacefill 25%; ';
        if ( currentStyle != 'select' ) {
            // this branch for first selection of session, or if no display style has been selected
            displayStyleScript = jmolDisplayStyleScriptFor( currentStyle );
        }
        // needs the reset if currentStyle is wireframe, at any rate (setting all to wireframe doesn't turn off spacefill)
        resetScript = "select all; wireframe off; spacefill off; cartoon off; ribbon off; rocket off; strand off; trace off; ";
        selectScript = resetScript + "select all; " + displayStyleScript + selectScript;
        document.jmolForm.showPDBcoords.value = positions;
    }

    // run the script
//    alert ( "calling jmolScriptWait with script: " + selectScript );
    jmolScriptWait( selectScript );

}

function resetHighlightsScript() {
    var currentHighlightsScript = '';
    if ( document.jmolForm.showPDBcoords.value ) {
        currentHighlightsScript = "select "
                                + document.jmolForm.showPDBcoords.value
                                + "; spacefill 60%; select all; ";
    }
    return currentHighlightsScript;
}

function jmolRenderDisplayStyle( choice ) {
    if ( choice == 'select' ) { return; }
    resetScript = "select all; wireframe off; spacefill off; cartoon off; ribbon off; rocket off; strand off; trace off; ";
    displayScript = resetScript + jmolDisplayStyleScriptFor( choice ) + resetHighlightsScript();
    jmolScriptWait( displayScript );
}

function jmolDisplayStyleScriptFor( choice ) {
    if ( choice == 'ballAndStick' ) { return "wireframe 20; spacefill 25%; " };
    if ( choice == 'spacefill' )    { return "spacefill; " };
    if ( choice == 'wireframe' )    { return "wireframe 50; " };
    if ( choice == 'ribbons' )      { return "ribbon; " };
    if ( choice == 'cartoon' )      { return "cartoon; " };
    if ( choice == 'rockets' )      { return "rockets; " };
    if ( choice == 'strand' )       { return "strand; " };
    if ( choice == 'trace' )        { return "trace; " };
    if ( !choice )                  { return "" };
}

function jmolRenderColorScheme( choice ) {
    if ( choice == 'select' ) { return; }
    colorScript = jmolColorSchemeScriptFor( choice );
    jmolScriptWait( colorScript );
}

function jmolColorSchemeScriptFor( choice ) {
    if ( choice == 'cpk' )         { return "color cpk; " };
    if ( choice == 'structure' )   { return "color structure; " };
    if ( choice == 'group' )       { return "color group; " };
    if ( choice == 'temperature' ) { return "color temperature; " };
    if ( choice == 'amino' )       { return "color amino; " };
    if ( choice == 'shapely' )     { return "color shapely; " };
    if ( choice == 'select' )      { return "" };
}
