//
// textcook.js
//
// JavaScript subroutines for text page cookies (single text page)
//
// created 2009-02-21 - Adrian Dover
//  edited 2009-02-22 - added 10 placemark limit and capital default place; some debugging
//         2009-02-26 - to cope with prefaces, default font size now 11pt
//         2009-03-05 - added cookie background colour to functions
//         2009-03-05 - changed from placemarks to textlabels
//         2009-04-20 - removed prefaces conditions (now in _multi version)
//

//
// this function unpacks the cookie and updates the text page settings from
// the first four and loads the user's textlabels into the correct object 
//

function applyCookieSettings()
{

  // get URL: Firefox and Opera, at least, have it as location
  //          but W3C standards have URL
  if ( document.URL != null ) {
    var texturl = document.URL.toString();
  } else if ( document.location != null ) {
    var texturl = document.location.toString();
  }

  //
  // extract cookie values
  //

  var allcookies = document.cookie;
  var setpos = allcookies.indexOf("settings");

  if ( setpos != -1 ) {

    var start = setpos + 9;
    var end = allcookies.indexOf(";",start);
    if ( end == -1 ) { end = allcookies.length; }
    var settings = allcookies.substring(start,end).toString();

    // query: why doesn't ()* work? I've had to repeat ()? to a limit of 10 textlabels
    // var values = settings.match(/bgcolour(\w+):fontsize(\d+)pt:linkcolour(\w+):statuscolour(\w+):([^:]+ch\d\dp\d\d\d:)+/);
    var values = settings.match(/bgcolour(\w+):fontsize(\d+)pt:linkcolour(\w+):statuscolour(\w+):([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?/);

    // alert("in function apply cookie settings\nvalues : " + values[0] + "\n" + values[1] + "  " + values[2] + "  " + values[3] + "  " + values[4] + "  " + values[5] + "  " + values[6]);

    //
    // handle user's textlabels: load into textlabels object
    //

    if  ( values[5] != undefined ) {

      if ( window.textlabels == undefined ) {
        window.textlabels = new Object();
      }

      // reminder: can't use for count loop because of null array entries created by
      // ()* bug forcing explicit repeats of the () pattern in the regext above

      var count = 5;
      var defaultLabelId;

      while ( values[count] != null ) {

        var nameIdPair = values[count].match(/(.+)(ch\d\dp\d\d\d):$/);
	var labelName = unescape(nameIdPair[1]);
	var labelId = nameIdPair[2];

        window.textlabels[labelName] = labelId;

        if ( labelName.search(/[A-Z]/) == 0 ) {
          defaultLabelId = labelId;
          // alert("default labelname: " + labelName + " with id " + defaultLabelId);
        }

        count++;

      }

      // if one of the names started with a capital letter
      if ( defaultLabelId != undefined ) {

        // alert("current URL: " + texturl);

        // if this page is not loading with a fragment identifier
        // go to default
        if ( texturl.indexOf('#') < 0 ) {
          // alert("# not found in " + texturl);
          // move text frame to the id for the capitalized textlabeler
          parent.text.location = texturl + '#' + defaultLabelId;
        // } else {
        //   alert("# found in " + texturl);
        }
      }

    }


    //
    // handle background colour
    //

    // reminder: values[0] contains whole match
    if ( values[1] != "cream" ) {

      // background is not default: make it brown with salmon text
      document.body.style.backgroundColor='#402020';
      document.body.style.color='#ffcc99';

    }


    //
    // handle point size
    //

    if ( values[2] != "11" ) {

      // point size is not the default so load each text paragraph with it
      var paratags = document.getElementsByTagName('p'); 

      // ignore three links in footer, and adjust for array index = length - 1
      var maxindex = paratags.length - 4;

      // extract point size as number and calculate matching line height and top margin
      var pointsize = parseInt(values[2]);
      var lineheight = pointsize + 2;
      var margintop = 1 - pointsize;

      // skip first para (index 0) as it's the 'reveled' message
      for (count = 1 ; count < maxindex ; count++ ) {

        // set the new font size
        paratags[count].style.fontSize = pointsize + "pt";

        // set line height to match new size
        paratags[count].style.lineHeight = lineheight + "pt";

        // set negative top margin to avoid large gaps between paragraphs
        paratags[count].style.marginTop = margintop + "pt";

      }

      // if stored size is at a limit: change relevant action text color on menu immediately)
      if ( pointsize <= 8 ) {
        parent.menu.document.getElementById('fontsmaller').style.color = "#ffcc99";
      } else if ( pointsize >= 24 ) {
        parent.menu.document.getElementById('fontlarger').style.color = "#ffcc99";
      }

    // alert("applied settings, third para: size : " + paratags[2].style.fontSize + "  height: " + paratags[2].style.lineHeight + "  margin: " + paratags[2].style.marginTop);

    }


    //
    // handle link colour (stored according to background colour and visible or not)
    //

    if ( values[3] == "brown" || values[3] == "orange" || values[3] == "salmon" ) {

      // make array of all anchor elements
      var anchorTags = document.getElementsByTagName('a');

      // ignore three links in footer, and adjust for array index = length - 1
      var maxindex = anchorTags.length - 4;

      if ( values[3] == "brown" ) {
        // set links to brown
        for (count = 0 ; count < maxindex ; count++ ) {
          anchorTags[count].style.color = '#402020';
        }
      } else if ( values[3] == "salmon" ) {
        // set links to salmon
        for (count = 0 ; count < maxindex ; count++ ) {
          anchorTags[count].style.color = '#ffcc99';
        }
      } else {
        // set links to orange
        for (count = 0 ; count < maxindex ; count++ ) {
          anchorTags[count].style.color = '#ff6600';
        }
      }

    }


    //
    // handle status colour
    //

    if ( values[4] == "brown" ) {
      // set status message to brown
      document.getElementById('linkstat').style.color = '#402020';
    } else if ( values[4] == "salmon" ) {
      // set status message to salmon
      document.getElementById('linkstat').style.color = '#ffcc99';
    } else {
      // status message not set or set to background colour: put message to cream
      document.getElementById('linkstat').style.color = '#fff0d7';
    }


  // end of cookie values found condition
  }

}


//
// ----- this function called by other routines and by text unload -----
//

function createCookie()
{

  var creationRequired = false;

  //
  // get current date and add three months for cookie expiry date
  //

  var toexpire = new Date();
  var newmonth = toexpire.getMonth() + 3;
  var newyear = toexpire.getFullYear();
  if ( newmonth > 11 ) {
    newmonth -= 12;
    newyear += 1;
  }
  toexpire.setFullYear(newyear);
  toexpire.setMonth(newmonth);


  //
  // get value of background colour, or default
  //

  if ( document.body.style.backgroundColor == 'rgb(64, 32, 32)'
    || document.body.style.backgroundColor == '#402020' ) {

    // text background is brown
    var currentBackground = "brown";
    creationRequired = true;
  } else {
    var currentBackground = "cream";
  }


  //
  // get value of font size, or default
  //

  var paratags = document.getElementsByTagName('p'); 

  // set the default font size (skip first para)
  var sampleFontSize = paratags[1].style.fontSize.toString();

  if ( sampleFontSize.search(/pt/) >= 0 ) {
    // font size is set
    var currentFontSize = sampleFontSize;
  } else {
    var currentFontSize = "11pt";
  }

  if ( currentFontSize != '11pt' ) {
    creationRequired = true;
  }


  //
  // get value of link colour, or default by text type
  //

  // get URL: Firefox and Opera, at least, have it as location
  //          but W3C standards have URL
  if ( document.URL != null ) {
    var texturl = document.URL.toString();
  } else if ( document.location != null ) {
    var texturl = document.location.toString();
  }

  // make array of all anchor elements
  var anchorTags = document.getElementsByTagName('a');

  // reminder: Mozilla (Firefox) returns rgb(i, j, k), Opera returns #rrggbb

  // get current link colour if set
  if ( anchorTags[0].style.color == 'rgb(255, 102, 0)' || anchorTags[0].style.color == '#ff6600' ) {
    // alert("matched colour:\n" + anchorTags[0].style.color);
    var currentLinkColour = "orange";
  } else if ( anchorTags[0].style.color == 'rgb(255, 204, 153)' || anchorTags[0].style.color == '#ffcc99' ) {
    // alert("matched colour:\n" + anchorTags[0].style.color);
    var currentLinkColour = "salmon";
  } else if ( anchorTags[0].style.color == 'rgb(64, 64, 32)' || anchorTags[0].style.color == '#402020' ) {
    // alert("matched colour:\n" + anchorTags[0].style.color);
    var currentLinkColour = "brown";
  } else {
    // current link colour not set: take default colour
    var currentLinkColour = "brown";
  }

  if ( currentLinkColour == 'orange' ) {
    creationRequired = true;
  }


  // now calculate status message colour
  if ( currentLinkColour == "orange" || currentLinkColour == "salmon" ) {
    var statusColour = "brown";
  } else {
    var statusColour = "cream";
  }


  //
  // now write values to a cookie string
  //

  // first get display values
  var cookieValues = "bgcolour" + currentBackground + ":fontsize" + currentFontSize + ":linkcolour" + currentLinkColour + ":statuscolour" + statusColour + ":";

  if ( window.textlabels != undefined ) {

    // then write all the textlabel name and id pairs stored in the textlabels object:
    // put them in alphabetical order
    // (reminder: sort() doesn't work on window.textlabels object)
    var holding = new Array;
    var holdcount = 0;
    for ( labelName in window.textlabels ) {
      holding[holdcount] = labelName;
      holdcount++;
      // alert("sort storing " + labelName);
    }
    holding.sort();
    for ( sortedcount = 0 ; sortedcount < holding.length ; sortedcount++ ) {
      var thisLabelname = holding[sortedcount];
      // alert("cookie storing " + thisLabelname);
      cookieValues += escape(thisLabelname) + window.textlabels[thisLabelname] + ':';
    }

    creationRequired = true;

  }


  //
  // finally create cookie for this URL if a display value is non-standard
  // or there are textlabels (flag), or if a cookie already exists (it
  // might need updating, even with standard display values and no textlabels)
  // reminder: non-existent cookie returns empty string not null|undefined !!
  //   || document.cookie != null  || document.cookie != undefined
  //

  if ( creationRequired == true || document.cookie != '') {
    // reminder: with three-months expiry date,
    //           but don't need to monkey with path, domain or secure FTB
    document.cookie = "settings=" + cookieValues + "; expires=" + toexpire.toGMTString();
  }

}


//
// ----- allow user to delete any textlabels -----
//

function deleteTextlabel()
{

  if ( window.textlabels == undefined ) {

    alert("Sorry: no stored textlabels were found.\nIf you have previously created some for this\ntext, the three-month lifetime may have expired.");

  } else {

    // cycle through them, in alphabetical order, offering delete on each

    // (reminder: sort() doesn't work on window.textlabels object)
    var holding = new Array;
    var holdcount = 0;
    for ( labelName in window.textlabels ) {
      holding[holdcount] = labelName;
      holdcount++;
      // alert("sort storing " + labelName);
    }
    holding.sort();
    for ( sortedcount = 0 ; sortedcount < holding.length ; sortedcount++ ) {
      var thisLabelname = holding[sortedcount];
      if ( confirm("Do you want to proceed with the delete operation on the\ntextlabel you have named : '" + thisLabelname + "' ?\n(click 'cancel' to keep it)") ) {
        delete window.textlabels[thisLabelname];
      }
    }

    // update the revised cookie
    createCookie();

    // now reload the menu to remove deleted textlabels from the menu
    parent.menu.location.reload('');
    // parent.menu.location = "menu.htm#siteopts";

  }

}


//
// ----- this function only required for testing -----
//

function displayCookieSettings()
{

  //
  // extract cookie values
  //

  var allcookies = document.cookie;
  var setpos = allcookies.indexOf("settings");

  if ( setpos != -1 ) {

    var start = setpos + 9;
    var end = allcookies.indexOf(";",start);
    if ( end == -1 ) { end = allcookies.length; }
    var settings = allcookies.substring(start,end).toString();

    // query: why doesn't ()* work? I've had to repeat ()? to a limit of 10 textlabels
    var values = settings.match(/bgcolour(\w+):fontsize(\d+)pt:linkcolour(\w+):statuscolour(\w+):([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?([^:]+ch\d\dp\d\d\d:)?/);

    // alert("in function apply cookie settings\nvalues :\n1: " + values[1] + " 2: " + values[2] + " 3: " + values[3] + " 4: " + values[4] + "\n5: " + values[5] + " 6: " + values[6] + "\n7: " + values[7] + " 8: " + values[8] + "\n9: " + values[9] + " 10: " + values[10] + "\n11: " + values[11] + " 12: " + values[12]);
    alert("in textcook function display cookie settings\nvalues :\n1: " + unescape(values[1]) + " 2: " + unescape(values[2]) + " 3: " + unescape(values[3]) + " 4: " + unescape(values[4]) + "\n5: " + unescape(values[5]) + " 6: " + unescape(values[6]) + "\n7: " + unescape(values[7]) + " 8: " + unescape(values[8]) + "\n9: " + unescape(values[9]) + " 10: " + unescape(values[10]) + "\n11: " + unescape(values[11]) + " 12: " + unescape(values[12]) + "\n13: " + unescape(values[13]) + " 14: " + unescape(values[14]));

  } else {

    alert("in textcook function display cookie settings:\nno 'settings' cookie found for this text");

  }

}


//
// ----- allow user to create a textlabel by double click on paragraph -----
//

function makeLabel(givenid)
{

  //
  // create new array (if not created by page load)
  //

  if ( window.textlabels == undefined ) {
    window.textlabels = new Object();
  } else {
    var markCount = 0;
    for ( existingLabelname in window.textlabels ) {
      ++markCount;
    }
    if ( markCount >= 10 ) {
      alert("sorry: you already have 10 textlabels for this text:\nplease use the 'delete textlabel(s)' option\nto remove unwanted ones, before adding more");
      return;
    }
  }

  var labelName =  prompt("Please enter a name for this textlabel, to appear on the menu.\n\n"
			+ "You should start the name with a letter, for sensible filing.\n"
			+ "If you start with a capital letter, the text will load to this\n"
			+ "point next time you access it with the 'text (XHTML)' option.\n"
			+ "Such a default label will replace any previous default.\n", "");

  // handle user clicking 'cancel' button on prompt box
  if ( labelName == null ) return true;

  // alert("labelname element " + labelName + " to test");

  //
  // if user has started with a capital letter:
  // replace any uppercase intial on existing textlabel names
  //

  if ( labelName.search(/[A-Z]/) == 0 ) {

    for ( existingLabelname in window.textlabels ) {
      var firstCharacter = existingLabelname.substr(0,1);
      var remainingCharacters = existingLabelname.substr(1);
      // alert("first char : " + firstCharacter);
      if ( firstCharacter.search(/[A-Z]/) > -1 ) {
        alert("warning : " + labelName + " is replacing " + existingLabelname + " as the default");
        // why doesn't replace method work?
        var newLabelname = firstCharacter.toLowerCase() + remainingCharacters;
        window.textlabels[newLabelname] = window.textlabels[existingLabelname];
	delete window.textlabels[existingLabelname];
      }
    }

  }

  // reminder: prefaces have function call argument with text no. hardcoded in 'ch' element

  //
  // set the paragraph id (given as argument) for this textlabel name
  // reminder: silently overwrite any existing id for this name? OR prompt user (not recursive)
  //

  if ( window.textlabels[labelName] == undefined ) {
    window.textlabels[labelName] = givenid;
  } else {
    alert("labelname element " + labelName + " already in use: values will be updated");
  }

  // now call function to create the cookie (with display values included)
  createCookie();

  // now reload the menu to pick up the new textlabeler name
  parent.menu.location.reload();

}

// end of james/javas/textcook.js

