/**********
     TITLE: Music Object Extension - Wizards
   VERSION: 1.1.0
    AUTHOR: Chris van Rensburg
 COPYRIGHT: 1996-1999 Beatnik, Inc. All Rights Reserved
  REQUIRES: music-object.js (3.1.0 or higher)
**********/

function mo_escapeStr (sourceStr) {
	var result = '';
	for (var charNo = 0; charNo < sourceStr.length; charNo++) {
		var currentChar = sourceStr.charAt (charNo);
		if (currentChar == "'" || currentChar == '"' || currentChar == '\\') result += '\\';
		result += currentChar;
	}
	return result;
}

function mo_wireElement (windowHandle,element,elementName) {
	var args = mo_wireElement.arguments;
	for (var argNo = 3; argNo < args.length;argNo++) {
		var eventName = args [argNo];
		mo_addEventHandler (windowHandle,element,eventName,'eval (mo_' + elementName + eventName.charAt (0).toUpperCase () + eventName.substring (1) + 'Handler)');
	}
}

function mo_wireForm (windowHandle,formHandle) {
	with (formHandle) {
		for (var elementNo = 0; elementNo < elements.length; elementNo++) {
			var element = elements [elementNo];
			if (element.type == 'checkbox') {
				mo_addEventHandler (windowHandle,element,'onclick','eval (this.checked ? mo_checkboxCheckHandler : mo_checkboxUncheckHandler)');
			} else if (element.type == 'radio') {
				mo_wireElement (windowHandle,element,'radio','onclick');
			} else if (element.type == 'select-one') {
				mo_wireElement (windowHandle,element,'list','onfocus','onchange','onblur');
			} else if (element.type == 'select-multiple') {
				mo_wireElement (windowHandle,element,'multilist','onfocus','onchange','onblur');
			} else if (element.type == 'text') {
				mo_wireElement (windowHandle,element,'textbox','onfocus','onblur');
			} else if (element.type == 'textarea') {
				mo_wireElement (windowHandle,element,'textarea','onfocus','onblur');
			} else if (element.type == 'button') {
				mo_wireElement (windowHandle,element,'button','onclick');
			} else if (element.type == 'reset') {
				mo_wireElement (windowHandle,element,'reset','onclick');
			} else if (element.type == 'submit') {
				mo_wireElement (windowHandle,element,'submit','onclick');
			}
		}
	}
}

function mo_joinStatements () {
	var
		args = mo_joinStatements.arguments,
		result = ''
	;
	for (var argNo = 0; argNo < args.length; argNo++)
		result += (args [argNo] != '') ? (((result != '') ? '; ' : '') + args [argNo]) : ''
	;
	return result;
}

function mo_updateHandler (objectHandle,handlerName,newValue,updateType) {
	var oldValue = (typeof (objectHandle [handlerName]) == 'undefined') ? '' : objectHandle [handlerName];
	objectHandle [handlerName] = (updateType == 'replace') ? newValue : ((updateType == 'merge with') ? ((newValue != '') ? newValue : oldValue) : ((updateType == 'add to') ? mo_joinStatements (oldValue,newValue) : ((updateType == 'fill in') ? ((oldValue == '') ? newValue : oldValue) : oldValue)));
}

function mo_sonifyFormsWithHandlers (checkboxCheck,checkboxUncheck,radioButton,listFocus,listChoose,listBlur,multilistFocus,multilistChoose,multilistBlur,textboxFocus,textboxBlur,buttonClick,formReset,formSubmit,updateType,windowHandle) {
	windowHandle = (typeof (windowHandle) != 'undefined') ? windowHandle : ((typeof (this.document) != 'undefined') ? this : window);
	if (typeof (updateType) != 'string') updateType = 'add to';
	if (typeof (windowHandle.mo_formsSonified) == 'undefined') {
		with (windowHandle) {
			for (var formNo = 0; formNo < document.forms.length; formNo++)
				mo_wireForm (windowHandle,document.forms [formNo])
			;
			if (typeof (document.layers) != 'undefined') {
				for (var layerNo = 0; layerNo < document.layers.length; layerNo++) {
					docHandle = document.layers [layerNo].document;
					for (var formNo = 0; formNo < docHandle.forms.length; formNo++)
						mo_wireForm (windowHandle,docHandle.forms [formNo])
					;
				}
			}
		}
		windowHandle.mo_formsSonified = true;
	}
	var
		events = new Array ('checkboxCheck','checkboxUncheck','radioOnclick','listOnfocus','listOnchange','listOnblur','multilistOnfocus','multilistOnchange','multilistOnblur','textboxOnfocus','textboxOnblur','buttonOnclick','resetOnclick','submitOnclick'),
		args = mo_sonifyFormsWithHandlers.arguments
	;
	for (var eventNo = 0; eventNo < events.length; eventNo++)
		mo_updateHandler (windowHandle,'mo_' + events [eventNo] + 'Handler',args [eventNo],updateType)
	;
	mo_updateHandler (windowHandle,'mo_textareaOnfocusHandler',textboxFocus,updateType);
	mo_updateHandler (windowHandle,'mo_textareaOnblurHandler',textboxBlur,updateType);
}

function mo_wizardSound (_groovoidName) {
	return (_groovoidName > ' ') ? ((typeof (mo_wizardTarget) == 'string') ? ('b_playGroovoid (\'' + mo_wizardTarget + '\',\'auto\',\'' + _groovoidName + '\',100)') : (mo_wizardTarget.objectName + '.play (\'' + _groovoidName + '\')')) : '';
}

function mo_wizardSoundStop (_groovoidName) {
	return (_groovoidName > ' ') ? ((typeof (mo_wizardTarget) == 'string') ? ('b_stopGroovoid (\'' + mo_wizardTarget + '\',\'' + _groovoidName + '\',150)') : (mo_wizardTarget.objectName + '.stop (150)')) : '';
}

function mo_sonifyFormsWithGroovoids (target,checkboxCheck,checkboxUncheck,radioButton,listFocus,listChoose,listBlur,multilistFocus,multilistChoose,multilistBlur,textboxFocus,textboxBlur,buttonClick,formReset,formSubmit,updateType,windowHandle) {
	if (Music.enabled) {
		mo_wizardTarget = target;
		mo_sonifyFormsWithHandlers (
			mo_wizardSound (checkboxCheck),
			mo_wizardSound (checkboxUncheck),
			mo_wizardSound (radioButton),
			mo_wizardSound (listFocus),
			mo_joinStatements (mo_wizardSoundStop (listFocus),mo_wizardSound (listChoose)),
			mo_joinStatements (mo_wizardSoundStop (listFocus),mo_wizardSound (listBlur)),
			mo_wizardSound (multilistFocus),
			mo_joinStatements (mo_wizardSoundStop (multilistFocus),mo_wizardSound (multilistChoose)),
			mo_joinStatements (mo_wizardSoundStop (multilistFocus),mo_wizardSound (multilistBlur)),
			mo_wizardSound (textboxFocus),
			mo_joinStatements (mo_wizardSoundStop (textboxFocus),mo_wizardSound (textboxBlur)),
			mo_wizardSound (buttonClick),
			mo_wizardSound (formReset),
			mo_wizardSound (formSubmit),
			updateType,
			(typeof (windowHandle) != 'undefined') ? windowHandle : ((typeof (this.document) != 'undefined') ? this : window)
		);
	}
}

function mo_addLinkLabel () {}

function mo_linkHandlersStr (link) {
	return ('' + link.onmouseover) + ('' + link.onmouseout) + ('' + link.onclick);
}

function mo_linkHasLabel (link,label) {
	var linkHandlersStr = mo_linkHandlersStr (link);
	return linkHandlersStr.indexOf ('addLinkLabel') != -1 && mo_stringHasAny (linkHandlersStr,"'" + label + "'",'"' + label + '"');
}

function mo_wireLink (windowHandle,link) {
	if (typeof (link ['mo_wired']) == 'undefined') {
		mo_addEventHandler (windowHandle,link,'onclick','eval (this.mo_onclick); eval (this.mo_clearHover)');
		mo_addEventHandler (windowHandle,link,'onmouseover','eval (this.mo_onmouseover); eval (this.mo_setHover)');
		mo_addEventHandler (windowHandle,link,'onmouseout','eval (this.mo_onmouseout); eval (this.mo_clearHover)');
		link ['mo_wired'] = true;
	}
}

function mo_linkHandler (linkNoStr,handler) {
	return ((handler != '') ? linkNoStr : '') + handler;
}

function mo_sonifyLinksWithHandlers (linkClick,linkOver,linkOut,linkHover,hoverDelay,startLinkLabel,endLinkLabel,linkLabelPrefix,updateType,windowHandle) {
	windowHandle = (typeof (windowHandle) != 'undefined') ? windowHandle : ((typeof (this.document) != 'undefined') ? this : window);
	var
		docLinks = windowHandle.document.links,
		startLinkNo = 0,
		endLinkNo = docLinks.length - 1
	;
	if (typeof (hoverDelay) != 'number') hoverDelay = 350;
	if (typeof (linkLabelPrefix) != 'string') linkLabelPrefix = '';
	if (typeof (updateType) != 'string') updateType = 'add to';
	if (typeof (startLinkLabel) == 'string' && startLinkLabel != '[first link]' && startLinkLabel != '') {
		for (var linkNo = 0; linkNo < docLinks.length; linkNo++) {
			if (mo_linkHasLabel (docLinks [linkNo],startLinkLabel)) {
				startLinkNo = linkNo;
				break;
			}
		}
	}
	if (typeof (endLinkLabel) == 'string' && endLinkLabel != '[last link]' && endLinkLabel != '') {
		for (var linkNo = 0; linkNo < docLinks.length; linkNo++) {
			if (mo_linkHasLabel (docLinks [linkNo],endLinkLabel)) {
				endLinkNo = linkNo;
				break;
			}
		}
	}
	var
		isHover = (typeof (linkHover) == 'string' && linkHover != ''),
		isReversed = startLinkNo > endLinkNo,
		linkInc = isReversed ? -1 : 1
	;
	var
		linkNo = startLinkNo,
		linksFound = 0,
		linksToScan = (endLinkNo - startLinkNo) * linkInc + 1
	;
	for (var linksScanned = 0; linksScanned < linksToScan; linksScanned++) {
		var
			link = docLinks [linkNo],
			linkHandlersStr = mo_linkHandlersStr (link)
		;
		if (linkLabelPrefix == '' || (linkHandlersStr.indexOf ('addLinkLabel') != -1 && mo_stringHasAny (linkHandlersStr,"'" + linkLabelPrefix,'"' + linkLabelPrefix))) {
			var linkNoStr = 'linkNo = ' + linksFound + ';';
			mo_wireLink (windowHandle,link);
			if (isHover) Music.hoverTimeouts++;
			mo_updateHandler (link,'mo_onclick',mo_linkHandler (linkNoStr,linkClick),updateType);
			mo_updateHandler (link,'mo_onmouseover',mo_linkHandler (linkNoStr,linkOver),updateType);
			mo_updateHandler (link,'mo_onmouseout',mo_linkHandler (linkNoStr,linkOut),updateType);
			mo_updateHandler (link,'mo_setHover',(isHover ? ('Music.hoverTimeout' + Music.hoverTimeouts + ' = setTimeout (\'' + mo_linkHandler (linkNoStr,mo_escapeStr (linkHover)) + '\',' + hoverDelay + ')') : ''),updateType);
			mo_updateHandler (link,'mo_clearHover',(isHover ? 'clearTimeout (Music.hoverTimeout' + Music.hoverTimeouts + ')' : ''),updateType);
			linksFound++;
		}
		linkNo += linkInc;
	}
}

function mo_sonifyLinksWithGroovoids (target,linkClick,linkOver,linkOut,linkHover,hoverDelay,startLinkLabel,endLinkLabel,linkLabelPrefix,updateType,windowHandle) {
	if (Music.enabled) {
		mo_wizardTarget = target;
		mo_sonifyLinksWithHandlers (
			mo_joinStatements (
				mo_wizardSoundStop (linkOver),
				mo_wizardSoundStop (linkHover),
				mo_wizardSound (linkClick)
			),
			mo_wizardSound (linkOver),
			mo_joinStatements (
				mo_wizardSoundStop (linkOver),
				mo_wizardSoundStop (linkHover),
				mo_wizardSoundStop (linkClick),
				mo_wizardSound (linkOut)
			),
			mo_wizardSound (linkHover),
			hoverDelay,
			startLinkLabel,
			endLinkLabel,
			linkLabelPrefix,
			updateType,
			(typeof (windowHandle) != 'undefined') ? windowHandle : ((typeof (this.document) != 'undefined') ? this : window)
		);
	}
}

/*** Static Read-only Properties ***/

Music.hoverTimeouts = 0;

/*** Static Methods ***/

mo_addStaticMethods ('addLinkLabel','sonifyFormsWithGroovoids','sonifyFormsWithHandlers','sonifyLinksWithGroovoids','sonifyLinksWithHandlers');

