// NeumesXML visualization XSLT, JavaScript
// filename: NeumesXML_xsl.js
// version: 6 December 2006
// Copyright 2005-2006, Louis W. G. Barton


/*	*********************
	***  INLINE CODE  ***
	*********************
*/

/*	SET BROWSER VERSION
 *
 * To-do: normalize this.
 */
	/*
		if(document.getElementById) {  // Level 1 DOM
		} else if(document.all) {  // IE4 model
		} else if(document.layers) { }  // NS4 model
	*/
// Currently not used:
var ie=document.all;
var ns6=document.getElementById&&!document.all;
var ns=document.layers;


/*	**************************
	***  GLOBAL VARIABLES  ***
	**************************
*/

// Array constructor available as of JavaScript 1.1
var notationsWestern=new Array('Aquitanian', 'Sarum','square','St_Gall');
var notationsWesternNames=new Array('Aquitanian','Sarum', 'Square-neume','St. Gall');
var notationsEastern=new Array('Middle_Byzantine', 'Post_Byzantine');
var notationsEasternNames=new Array('Middle Byzantine', 'Post Byzantine');

/* Composition Object for Table of a COMPOUND GLYPH: */
var compTable=new Object();
compTable.R1C1='';  // Top Table Row (single cell, span) = position_1
compTable.R2C1='';  // 2nd TR above Glyph, Left Cell = position_2
compTable.R2C2='';  // 2nd TR above Glyph, Middle Cell = position_3
compTable.R2C3='';  // 2nd TR above Glyph, Right Cell = position_4
compTable.R3C1='';  // 1st TR above Glyph, Left Cell = position_5
compTable.R3C2='';  // 1st TR above Glyph, Middle Cell = position_6
compTable.R3C3='';  // 1st TR above Glyph, Right Cell = position_7
compTable.R4C1='';  // Base Glyph Row (single cell, span)
compTable.R5C1='';  // 1st TR below Glyph, Left Cell = position_14
compTable.R5C2='';  // 1st TR below Glyph, Middle Cell = position_15
compTable.R5C3='';  // 1st TR below Glyph, Right Cell = position_16
compTable.R6C1='';  // 2nd TR below Glyph, Left Cell = position_17
compTable.R6C2='';  // 2nd TR below Glyph, Middle Cell = position_18
compTable.R6C3='';  // 2nd TR below Glyph, Right Cell = position_19
compTable.R7C1='';  // Bottom Table Row (single cell, span) = position_20



/*	*****************************
	***  TRANSCRIPTION TABLE  ***
	*****************************
*/

/*	FN: OPEN the TRANSCRIPTION TABLE
 *
 * Note: Do Not Set width to 100%, else margins don't work.
 *
 * Dependencies:
 * - lmarginValue
 * - rmarginValue
 * - zoomValue
 */
function openTranscriptionTable() {
	document.write('<TABLE style="table-layout:fixed; display:block; ' +
	  'margin-left:' + lmarginValue + 'px; margin-right:' + rmarginValue +
	  'px; zoom:' + zoomValue + '%; text-align:left; word-wrap:break-word; ' +
	  'border-collapse:collapse; border-spacing: 0pt 0pt; padding:0px;">');
	return false;  // event handled
}  //end, openTranscriptionTable()



/*	****************************************
	***  POSITIONING of COMPOUND GLYPHS  ***
	****************************************
*/

/*	FN: CLEAR COMPOUND-NEUME TABLE
 *
 */
function clearCompTable() {
	for (i in compTable) {
		compTable[i]='';
	}
	return false;  // event handled
}  //end, clearCompTable()


/*	FN: OUTPUT COMPOUND-NEUME TABLE
 *
 * To do: Change class compositeNeume to compoundGlyph.
 *
 * Dependencies:
 * - CSS class compositeNeume
 * - CSS class stackedGlyph
 */
function outputCompTable() {
	document.writeln('<TABLE class="compositeNeume" CellSpacing="0" CellPadding="0">');
	document.write('<colgroup><col Width="0*"><col Width="*"><col Width="0*"></colgroup>');
	document.writeln('<tbody>');
	if (compTable.R1C1 != '') {
		document.writeln('<TR><TD class="stackedGlyph" ColSpan="3" Align="center">' +
		   compTable.R1C1 + '</TD></TR>');
	}
	if ( ('' != compTable.R2C1) || ('' != compTable.R2C2) || ('' != compTable.R2C3) ) {
		document.writeln('<TR>');
		document.writeln('<TD class="stackedGlyph" Align="left">' +
		   compTable.R2C1 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="center">' +
		   compTable.R2C2 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="right">' +
		   compTable.R2C3 + '</TD>');
		document.writeln('</TR>');
	}
	if ( ('' != compTable.R3C1) || ('' != compTable.R3C2) || ('' != compTable.R3C3) ) {
		document.writeln('<TR>');
		document.writeln('<TD class="stackedGlyph" Align="left">' +
		   compTable.R3C1 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="center">' +
		   compTable.R3C2 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="right">' +
		   compTable.R3C3 + '</TD>');
		document.writeln('</TR>');
	}
	/** Modify per glyph here: **/
	document.writeln('<TR><TD class="stackedGlyph" ColSpan="3" Align="center">' +
	   compTable.R4C1 + '</TD></TR>');
	if ( ('' != compTable.R5C1) || ('' != compTable.R5C2) || ('' != compTable.R5C3) ) {
		document.writeln('<TR>');
		document.writeln('<TD class="stackedGlyph" Align="left">' +
		   compTable.R5C1 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="center">' +
		   compTable.R5C2 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="right">' +
		   compTable.R5C3 + '</TD>');
		document.writeln('</TR>');
	}
	if ( ('' != compTable.R6C1) || ('' != compTable.R6C2) || ('' != compTable.R6C3) ) {
		document.writeln('<TR>');
		document.writeln('<TD class="stackedGlyph" Align="left">' +
		   compTable.R6C1 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="center">' +
		   compTable.R6C2 + '</TD>');
		document.writeln('<TD class="stackedGlyph" Align="right">' +
		   compTable.R6C3 + '</TD>');
		document.writeln('</TR>');
	}
	if ('' != compTable.R7C1) {
		document.writeln('<TR><TD class="stackedGlyph" ColSpan="3" Align="center">' +
		   compTable.R7C1 + '</TD></TR>');
	}
	document.writeln('</tbody></TABLE>');
	return false;  // event handled
}  //end, outputCompTable()



/*	************************************
	***  LEGEND and DISPLAY OPTIONS  ***
	************************************
*/
// Note: Keep the next three functions near the top for maintenance of paths.

/*	FN: SHOW HELP FILE
 *
 */
function showHelpFile() {
	var helpFile='http://www.scribeserver.com/NEUMES/help/visualization_help.htm';
	window.open(helpFile, '', 'toolbar=yes,menubar=yes,status=yes,scrollbars=yes,' +
	  'resizable=yes,left=0,top=0,width=' + scrWidth + ',height=' + scrHeight + '');
	return false;  // event handled
}  //end, showHelpFile()


/*	FN: SHOW NEUMESXML SOURCE CODE
 *
 */
function showSourceCode(filepathValue) {
	var showSourceCommand='http://www.scribeserver.com/servlet/' +
	  'NEUMES.NeumesXML.PushSrcServlet?filepath=';
	var showSourceURL=showSourceCommand + filepathValue;
	window.open(showSourceURL, '', 'menubar=yes,status=yes,scrollbars=yes,resizable=yes,' +
	  'left=0,top=0,width=' + scrWidth + ',height=' + scrHeight + '');
	return false;  // event handled
}  //end, showSourceCode()


/*	FN: SHOW NEUMES HOMEPAGE
 *
 */
function showHomepage() {
	window.open('http://purl.oclc.org/SCRIBE/NEUMES/', '_NEUMES',
	  'toolbar=yes,location=yes,menubar=yes,status=yes,scrollbars=yes,resizable=yes,' +
	  'left=0,top=0,width=' + scrWidth + ',height=' + scrHeight + '');
	return false;  // event handled
}  //end, showHomepage()


/*	FN: RANDID
 *
 * [Adaptated from Central Randomizer 1.3 (C) 1997 by Paul Houle]
 */
function randID(ceiling) {
	seed=(seed*9301+49297) % 233280;
	return Math.ceil(seed/(233280.0) * ceiling);
}  //end, randID()


/*	FN: OPEN POPUP
 *
 * [To do: substitute IFrame if avail.]
 */
function pop(msg) {
	confirm(msg);  // no beep
	return false;  // event handled
}  //end, pop()


/*	FN: EVENT, IMG LOAD ERROR
 *
 * Stores filenames of images not found.
 *
 * Dependencies:
 * - imgColorPath
 */
function imgErr(imgName) {
	if (imgs_not_found.indexOf(imgName) == -1) {
		imgs_not_found=imgs_not_found + imgColorPath + imgName + ' ';
	}
	return false;  // event handled
}  //end, imgErr()


/*	FN: SHOW LIST OF VISUALIZATION ERRORS
 *
 * Displays in TextArea.
 */
function showErrList() {
	var buildLine='';
	/* Show list of glyph images not found: */
	// is correct:
	if ('' != imgs_not_found) {
		buildLine=buildLine +
		  'The following glyph images are needed for this visualization,\n' +
		  'but were not found in the image filepath:\n';
		var imgTokens=imgs_not_found.split(' ');
		imgTokens.sort();
		buildLine=buildLine + imgTokens.join('\n');
	} else {
		buildLine=buildLine + 'There were no errors in visualization.';
	}
	confirm(buildLine);  // 'confirm' dialog
	return false;  // event handled
}  //end, showErrList()


/*	FN: IGNORE THE ENTER KEY IN TEXT FIELDS
 *
 */
function noEnter() {
	return !(window.event && window.event.keyCode == 13);
}  //end, noEnter()


/*	FN: CHECK WELL-FORMEDNESS OF USER-SUPPLIED URL
 *
 * Returns true if user-supplied URL is well-formed, else returns false.
 * [USE REGEX; cf, unescape()]
 */
function checkURL(userURL) {
	return true;  // noop
}  //end, checkURL()


/*	FN: PULLDOWN for Legend/Options
 *
 * Toggle open/closed.
 * Pass in String of section's ID
 *
 * Returns 'true' of handled OK, else 'false'.
 */
function pulldown(secID) {
	var imgID=secID + '-control';  // anchored IMG ID must be 'xxsection-control'
	var imgObj=null;  // temp handle, plus/minus control IMG
	var sectObj=null;  // temp handle, section (Table Row)

	if(document.getElementById) {  // Level 1 DOM
		imgObj=document.getElementById(imgID);
		sectObj=document.getElementById(secID);
	} else if(document.all) {  // IE4 model
		imgObj=document.all[imgID];
		sectObj=document.all[secID];
	} else if(document.layers) {  // NS4 model
		imgObj=document.layers[imgID];
		sectObj=document.layers[secID];
	}  //end, if/else browser model
	if ( (null == imgObj) || (null == sectObj) ) {
		return false;  // failure
	}

	if ('block' == sectObj.style.display) {
		imgObj.src=plus_img;
		sectObj.style.display='none';
	} else {  // default
		imgObj.src=minus_img;
		sectObj.style.display='block';
	}
	return true;  // OK
}  //end, pulldown()


/*	FN: READ STATE of CHECKBOXES, and SET VARS
 *
 * Dependencies:
 * - pitchtone_mvmtValue
 * - metadataValue
 */
function readCheckBoxes() {
	if (document.redisplayForm.pitchtone_mvmt.checked) {
		pitchtone_mvmtValue='no';
	} else {
		pitchtone_mvmtValue='yes';
	}
	if (document.redisplayForm.metadata.checked) {
		metadataValue='no';
		document.redisplayForm.newWindow.checked=true;
		document.redisplayForm.newWindow.disable;
		document.redisplayForm.newWindow.style.backgroundColor='gray';
	} else {
		metadataValue='yes';
		document.redisplayForm.newWindow.enable;
		document.redisplayForm.newWindow.style.backgroundColor='transparent';
	}
	if (document.redisplayForm.newWindow.checked) {
		newWindowValue='yes';
	} else {
		newWindowValue='no';
	}
	return false;  // event handled
}  //end, readCheckBoxes()


/*	FN: REDRAW DISPLAY WITH OPTIONS
 *
 * Note: "document.redisplayForm.background.value" does not work as expected;
 * therefore, we use "onclick" with the radio buttons to set bgValue directly.
 */
function redrawDisplay(magnification, userNotation_family, lmargin, rmargin, userURL) {
	/*	Local vars, from redisplayForm:
		magnification
		userNotation_family
		lmargin
		rmargin
		userURL
	*/
	var newZoom=parseInt(magnification);
	var newNotation=userNotation_family;
	var newImgpath='';  // user-supplied URL for glyphs
	if ((50 > newZoom) || (newZoom > 200)) {
		alert('To \'rescale\', please enter a number in the specified range only.');
		return(false);
	}
	var newLmargin=parseInt(lmargin);
	if ((0 > newLmargin) || (newLmargin > 200)) {
		alert('For margins, please enter a number between 0 and 200.');
		return(false);
	}
	var newRmargin=parseInt(rmargin);
	if ((0 > newRmargin) || (newRmargin > 200)) {
		alert('For margins, please enter a number between 0 and 200.');
		return(false);
	}
// is correct:
	if ('' != userURL) {
		if (!checkURL(userURL)) {
			return(false);  // cancel this
		}
		newImgpath=escape(userURL);  // normalize to transmissible chars
	}
	// Assemble the new URL:
	urlParams[zoomIndex]='zoom=' + newZoom;
	urlParams[notationIndex]='notation=' + newNotation;
	urlParams[bgIndex]='bg=' + bgValue;
	urlParams[pitchtone_mvmtIndex]='pitchtone_mvmt=' + pitchtone_mvmtValue;
	urlParams[metadataIndex]='metadata=' + metadataValue;
	urlParams[lmarginIndex]='lmargin=' + newLmargin;
	urlParams[rmarginIndex]='rmargin=' + newRmargin;
	urlParams[userImgPathIndex]='imgpath=' + newImgpath;
	var newURL=urlQuery[0] + '?' + urlParams.join('&amp;');
	if (newWindowValue == 'yes') {
		window.open(newURL, '', 'menubar=yes,status=yes,scrollbars=yes,resizable=yes,' +
		  'left=0,top=0,width=' + screen.width + ',height=' + screen.height);
	} else {
		window.location.replace(newURL);
	}
}  //end, redrawDisplay()

//[end, NeumesXML_xsl.js]
