//======================================================================
// DLMF Common Javascript
//======================================================================

//----------------------------------------------------------------------
// Basic Cookie support.

// A date in the past, for expiring cookies
var EXPIRE_NOW = new Date();
var EXPIRE_NEVER = new Date();
EXPIRE_NOW.setTime(EXPIRE_NOW.getTime() - 1000);
EXPIRE_NEVER.setFullYear(EXPIRE_NEVER.getFullYear() +1);

function readCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
	var c = ca[i];
	while (c.charAt(0)==' ') c = c.substring(1,c.length);
	if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null; }

//----------------------------------------------------------------------
// Basic CSS Class support

function addClass(node,classname){
    var oldclass = node.className;
    if(node && !isClass(node,classname)){
	node.className += (node.className ? " ":"")+classname; }}

function removeClass(node,classname){
    if(node){
	node.className = node.className.replace(new RegExp("\\b"+classname+"\\b"),'')
	    .replace(/^\s+/,'').replace(/\s+$/,''); }}

function isClass(node,classname){
    return node && node.className.search(new RegExp("\\b"+classname+"\\b")) >= 0; }

//======================================================================
// If there's a form and query data in the URL, prefill the form.
//======================================================================

function prefillForms(){
    var nforms = document.forms.length;
    if(nforms > 0){
	var query = window.document.location.search.substring(1);
	var pairs = query.split("&");
	for(var i = 0; i < pairs.length; i++){
	    var pos = pairs[i].indexOf('=');
	    if(pos == -1) continue;
	    var key = unescape(pairs[i].substring(0,pos));
	    // Note: values can be escaped two different ways.
	    var val = unescape(pairs[i].substring(pos+1).replace(/\+/g,' '));
	    for(var f=0; f<nforms; f++){
		var form = document.forms[f];
		for(var e=0; e < form.elements.length; e++){
		    var el = form.elements[e];
		    if(el.type == 'radio'){
			if((el.name == key) && (el.value == val)){
			    el.checked = true; }}
		    else if(el.name == key){
			el.value = val; }}}
	}}}

//======================================================================
// Stylesheet selection.
//======================================================================
// Adapted From http://www.alistapart.com/stories/alternate/  by Paul Snowden
// Saves a persistent cookie!.

var BODY = null;
var REQ_Style = readCookie("Style");
var DEF_Style = null;

// This contrivance attempts to find the body & set style BEFORE onload!
// to avoid visible switch of styles.
// But note: it's not guaranteed to happen before onload!!!
if(REQ_Style != null){
    var init_step=0;
    var timer = window.setInterval(function(){
	init_step++;
	if((typeof document.getElementsByTagName != 'undefined')
	   && (((BODY=document.getElementsByTagName('body')[0]) != null)
	       || (BODY=document.body) != null)){
	    if(DEF_Style == null) 
		DEF_Style = BODY.className.replace(/ /g,'#');
	    BODY.className = REQ_Style.replace(/#/g,' ');
	    window.clearInterval(timer); }
	if(init_step > 100){
	    window.clearInterval(timer); }},
	50); }

function updateCSSStyle() {
    if(BODY == null){
	BODY = document.getElementsByTagName('body')[0];
	if(DEF_Style == null)
	    DEF_Style = BODY.className.replace(/ /g,'#'); 
    }
    REQ_Style = readCookie("Style");
    BODY.className = (REQ_Style == null ? DEF_Style : REQ_Style).replace(/#/g,' ');
    // If a customize form is present, set fields
    if(document.getElementById("customize.form") != null){
	var classes = BODY.className.split(' ');
	for(i=0; i < classes.length; i++){
	    var radio = document.getElementById("choose_"+classes[i]);
	    if(radio){
		radio.checked = true; }}
	var format = readCookie("Format");
	if(format == null){
	    format = "auto"; }
	var radio = document.getElementById("choose_format_"+format);
	if(radio){
	    radio.checked = true; }
    }
    return true; }

// Used by Customization forms (if any).
function set_style(group,value){
    var classes = BODY.className.split(' ');
    var newstyle = "";
    var nondefault = false;
    for(i=0; i < classes.length; i++){
	var pair = classes[i].split('_');
	if(pair[0] == group){
	    pair[1] = value; }
	nondefault = nondefault || (pair[1] != 'default');
	newstyle += (newstyle == "" ? "" : "#");
	newstyle += pair[0]+'_'+pair[1]; }
    BODY.className = newstyle.replace(/#/g,' ');
    if(nondefault){
	document.cookie = "Style="+newstyle+";path=/;expires="+EXPIRE_NEVER; }
    else {
	document.cookie = "Style=false;path=/;expires="+EXPIRE_NOW; }
    return false; }

function set_format(value){
    if((value != null) && (value != "auto")){
	document.cookie = "Format="+value+";path=/;expires="+EXPIRE_NEVER; }
    else {
	document.cookie = "Format=false;path=/;expires="+EXPIRE_NOW; }
    return false; }

//======================================================================
// Highlighting the document portion identified by the document fragment.
//======================================================================
var SELECTED_ID='';

function hiliteFrag(){
    var id = window.document.location.hash.substr(1);
    if(id != SELECTED_ID){
	if(SELECTED_ID != ''){
	    var node = window.document.getElementById(SELECTED_ID);
	    removeClass(node,'selected'); }
	SELECTED_ID = id;
	if(id != ''){
	    var node = window.document.getElementById(id);
	    //	    if(isClass(node,'info')){
	    // addClass(node,'shown'); }
	    addClass(node,'selected'); }
    }}

//======================================================================
// Exposing the Info/metadata
//======================================================================
// Info boxes are visible by:
//  *  PopUp on mouseover of the Info icon
//     Uses info:hover in CSS
// They are "displayed" (in the document flow) by:
//  * toggling Show/Hide annotations 
//    which affects ALL infoboxes by adding class='shown'
//    sets sidewide cookie
//  * clicking an Info icon
//    which toggles that Info box by adding class='shown' 
//    adds/removes that id from page cookie.
//  * If frag ID (in url) is to an Info box.

// NOTE: IE doesn't seem to allow storing cookies PER PAGE (ie w/ path=page)
// rather it wants the whole directory. Thus ID's get prefixed w/ the page.

var SHOW_INFO=false;
var SHOWN_INFO = '';
var infoOpened = new Object();
var THISPAGE = window.document.location.pathname.replace(/^.*\//,'');
function updateInfo(){
    var doupdate = false;
    if((readCookie("ShowInfoAll") == 'true') != SHOW_INFO){
	SHOW_INFO = !SHOW_INFO;  doupdate = true;
	var n;
	n = document.getElementById('showinfo');
	if(n){ n.style.display=(SHOW_INFO ? 'none' : 'list-item'); }
	n = document.getElementById('hideinfo');
	if(n){ n.style.display=(SHOW_INFO ? 'list-item' : 'none'); }
    }
    var infocookie = readCookie("ShowInfo_"+THISPAGE);
    if(SHOWN_INFO != infocookie){
	SHOWN_INFO = infocookie; doupdate = true;
	infoOpened = new Object();
	if(infocookie){
	    var ids = infocookie.split('#');
	    for(i=0; i < ids.length; i++){  
		infoOpened[ids[i]]=ids[i]; }}}
    if(doupdate){
	var dls = document.getElementsByTagName('div');
	for(i=0; i < dls.length; i++){
	    if(isClass(dls[i],'info')){
		var id = dls[i].id;
		//if(SHOW_INFO || infoOpened[id] || (id == SELECTED_ID)){
		if(SHOW_INFO || infoOpened[id]){
		    addClass(dls[i],'shown'); }
		else
		    removeClass(dls[i],'shown'); }}}
}

// Show (all) Annotations button clicked
function showInfo(){
    document.cookie = "ShowInfoAll=true;path=/";
    //	window.alert("Cookie: "+document.cookie);
    updateInfo(); }

// Hide (all) Annotations button clicked
function hideInfo(){
    document.cookie = "ShowInfoAll=false;path=/;expires="+EXPIRE_NOW;
    //	window.alert("Cookie: "+document.cookie);
    updateInfo(); }

// Info icon clicked:
function toggleInfo(id){
    var info = document.getElementById(id);
    if(!SHOW_INFO && isClass(info,'info')){
	if(isClass(info,'shown')){
	    removeClass(info,'shown');
	    delete infoOpened[id]; }
	else {
	    addClass(info,'shown'); 
	    infoOpened[id]=id; }
	SHOWN_INFO='';
	for(var anid in infoOpened){
	    SHOWN_INFO += (SHOWN_INFO=='' ? '' : '#') + anid; }
	if(SHOWN_INFO == ""){
	    SHOWN_INFO=null;
	    document.cookie = "ShowInfo_"+THISPAGE+"=;expires="+EXPIRE_NOW; }
	else {
	    document.cookie = "ShowInfo_"+THISPAGE+"="+SHOWN_INFO; }
}}

//======================================================================
// Orchestrate the whole mess.
//======================================================================

// Note: onLoad doesn't (necessarily) get invoked via <back> or <forward>,
// or following a link within the same document.
// Since we're trying to track changes to cookies, stylesheets, #frag (!)
// we need to occasionally peek at the state & possibly refresh.
// So, we set a timer to check the document's URL every second and update if needed.

var PREV_COOKIE = "";
function do_refresh(){
    if(document.cookie != PREV_COOKIE){
	updateCSSStyle(); 
	updateInfo();
	PREV_COOKIE = document.cookie; }
    hiliteFrag(); 
}

function do_onload(){
    PREV_COOKIE = document.cookie;
    updateCSSStyle(); 
    updateInfo();  
    hiliteFrag(); 
    prefillForms();
    window.setInterval("do_refresh()",500); // Set timer to recover, if needed.

    return true; }

window.onload = do_onload;



