var TRY_TIMES = 3;

/**
 *  Translates instruction from Maori to English, or from English to Maori.
 *  inste: tag name of English instruction
 *  instm: tag name of Maori instruction
 */
function translateInst(inste, instm) {
    toggle(inste);
    toggle(instm);
}

/**
 The html layout for a question paragraph.

 <div class="question">
 <form action="" method="get" onsubmit="return false;">

 <!-- characters' image will display here -->
 <div class="character"></div>

 <div class="questiontext">

 <!-- question will display here -->
 <span>content ... </span>

 <!-- user can input, choose answer here -->
 <span class="input"> <input type="text" /> or <input type="radio" /> or <select> <option> </option> ... </select> </span>

 <!-- answer will display here -->
 <span class="answer">&nbsp;</span>

 </div>

 <!-- audio for question will display here -->
 <div class="audio">
 </div>

 <!-- Information to display here if answer is correct, include audio -->
 <div style="display: none">blah blah ...</div>

 <!-- Information to display here if answer is incorrect, include audio -->
 <div style="display: none">blah blah ...</div>

 </form>
 </div>
 */

/**
 Checks the whole form to see if all answers are right.
 */
function checkAnswer(theForm, answer) {
    theForm.elements["tryTimes"].value = parseInt(theForm.elements["tryTimes"].value) + 1;
    if (theForm.elements["tryTimes"].value >= TRY_TIMES) {
        // display reveal answer button
        theForm.elements["a3"].style.display = "";
    }

    var answers = answer.split("*");
    if (answers.length > 0) {
        var rightNum = 0;
        var questionNum = 0;
        for (var i = 0; i < answers.length; i++) {
            if (theForm.elements["q" + i]) {
                questionNum++;
                if (check(theForm.elements["q" + i], i, answer)) {
                    rightNum++;
                }
            }
            //checkAndReply(theForm.elements["q"+i], i, answer);
        }
        var answerElement = getAnswerElement(theForm.elements["q0"]);
        var rightElement = getElementWhenAnswerIsRight(answerElement);
        var wrongElement = getElementWhenAnswerIsWrong(answerElement);
        var imgDiv = getImgDiv(theForm.elements["q0"]);

        if (rightNum == questionNum) {          // if all answers are right
            // display right reply information
            if (!isEmpty(rightElement))
                rightElement.style.display = "";
            if (!isEmpty(wrongElement))
                wrongElement.style.display = "none";
            changeExpression(imgDiv, "right");
            theForm.elements["a2"].style.display = "none";
            theForm.elements["a3"].style.display = "none";
        } else if (rightNum == 0) {             // if none of answers is right
            // display wrong reply information
            if (!isEmpty(rightElement))
                rightElement.style.display = "none";
            if (!isEmpty(wrongElement))
                wrongElement.style.display = "";
            changeExpression(imgDiv, "wrong");
        } else {                                // some answers are right, some are wrong
            changeExpression(imgDiv, "");
        }
    }
    hideInputButton();
}

/**
 Reveals answers for the whole form.
 */
function revealAnswer(theForm, answer) {
    if (theForm.elements["tryTimes"].value < TRY_TIMES) {
        alert("Please have a try first.")
        return;
    }
    var answers = answer.split("*");
    if (answers.length > 0) {
        for (var i = 0; i < answers.length; i++) {
            var rightAnswers = answers[i].split("^");
            setElementValue(theForm.elements["q" + i], rightAnswers[0]);
        }
    }
}

/**
 Check if answer is right.

 Param:
 formItem:   form element to input answer
 num:        which question
 answer:     '*' separated answer string
 */
function check(formItem, num, answer) {
    // if answer is not right
    if (!rightAnswer(formItem, num, answer)) {
        // only change style for input box
        if ((formItem.nodeName == "INPUT") && (getElementType(formItem) == "text")) {
            setWrongStyle(formItem);
        } else {
            // for others, just display a dialog
           // alert("Try again");
        }
        //setFocus(formItem);
        return false;
    } else { // if answer is right
        // form element is wrapped by a span, which is followed by another span to display answer
        var answerElement = getAnswerElement(formItem);

        // set text to right answer
        if (answerElement && answerElement.firstChild) {
            answerElement.firstChild.nodeValue = getElementValue(getForm(formItem).elements["q" + num]);
        }

        // hide and remove form element's parent span,
        // then for radio button, all options will be hidden at the same time
        var itemToBeRemove = getWrapper(formItem);
        itemToBeRemove.style.display = "none";
        //itemToBeRemove.parentNode.removeChild(itemToBeRemove);
        return true;
    }
}

/** Remembers last focused input box
 * and show input buttons near input box
 */
function inputOnFocus(formItem) {
    if (formItem) {
        lastFocusedElement = formItem;
        setNormalStyle(formItem);
    }
    showInputButton(formItem);
}

/** remembers last focused input box */
function inputOnBlur(formItem) {
    //hideInputButton();
}

/** inputs maori charcter to last focused input box when click the button */
function clickButton(inputChar) {
    try {
		if (lastFocusedElement) {
			insertAtCursor(lastFocusedElement, inputChar);
			lastFocusedElement.focus();
		}
		else {
			alert("Please click an input box first.");
		}
	}
	catch(err) {
			alert("Please click an input box first.");
		
	}
}

/** shows input button */
function showInputButton(formItem) {
    var inputButton = getObj("inputButton");
    var OFFSET_X = 0;
    var OFFSET_Y = 30;
    if (inputButton) {
        //inputButton.style.top = (findPosY(formItem) + OFFSET_Y) + "px";
        //inputButton.style.left = (findPosX(formItem) + OFFSET_X) + "px";
        inputButton.style.display = 'block';
    }
}

/** hides input button */
function hideInputButton() {
    var inputButton = getObj("inputButton");
    if (inputButton)
        inputButton.style.display = 'none';
}

/** floats input bottons */
function floatInputButton() {
    var FIXED_TOP_OFFSET = 194;
    var inputButton = getObj("inputButton");
    var topOffset = 0;
    // get top offset for different browsers
    if (window && window.pageYOffset) {
        topOffset = window.pageYOffset;
    }
    if (document && document.body && document.body.scrollTop) {
        topOffset = document.body.scrollTop;
    }
    if (document && document.documentElement && document.documentElement.scrollTop) {
        topOffset = document.documentElement.scrollTop;
    }
    // if top offset is big than FIXED_TOP_OFFSET, display the input buttons at the top of the page
    if (topOffset > FIXED_TOP_OFFSET)
        inputButton.style.top = topOffset + "px";
    else // otherwise, in a fixed place
        inputButton.style.top = FIXED_TOP_OFFSET + "px";
    var winW;
    if (window.innerWidth)
        winW = window.innerWidth;
    if (document.body.offsetWidth)
        winW = document.body.offsetWidth;
    inputButton.style.left = (winW / 2)-110 + "px";
	//inputButton.style.left = (winW / 2 + 100) + "px";
    // inputButton.style.display = 'block';
}

/** sets input box width according answer's length */
function setInputBoxWidth(theForm, answer) {
    var MAXIMIUM_LENGTH = 77;
    var answers = answer.split("*");
    for (var i = 0; i < answers.length; i++) {
        var formItem = theForm.elements["q" + i];
        var formType = getElementType(formItem);
        if (formType == 'text') {
            var rightAnswers = answers[i].split("^");
            var answerLen = 0;
            for (var j = 0; j < rightAnswers.length; j++) {
                if (rightAnswers[j].length > answerLen)
                    answerLen = rightAnswers[j].length;
            }
            if (answerLen > MAXIMIUM_LENGTH)
                formItem.style.width = ( MAXIMIUM_LENGTH * 8) + "px";
            else
                formItem.style.width = ( (answerLen + 1) * 8) + "px";
        }
    }
}

/** ---------- PRIVATE FUNCTIONS ---------- */

/** inserts string at cursor of an input box */
function insertAtCursor(myField, myValue) {
    //IE support
    if (document.selection) {
        myField.focus();
        sel = document.selection.createRange();
        sel.text = myValue;
    }
    //MOZILLA/NETSCAPE support
    else if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
                + myValue
                + myField.value.substring(endPos, myField.value.length);
        // change cursor position of input box
        myField.selectionStart = startPos + myValue.length;
        myField.selectionEnd = myField.selectionStart;
    } else {
        myField.value += myValue;
    }
}

/** Sets input box's style if answer is wrong */
function setWrongStyle(formItem) {
    formItem.style.color = "#ff0000";
    formItem.style.fontWeight = "normal";
    // formItem.style.textDecoration = "line-through";
}

/** Sets input box's style to normal */
function setNormalStyle(formItem) {
    formItem.style.color = "#000000";
    formItem.style.fontWeight = "normal";
    // formItem.style.textDecoration = "none";
}

/** returns parent node of a form item */
function getParentNode(formItem) {
    if (formItem) {
        // if this form item has parent, return its parent
        if (formItem.parentNode) {
            return formItem.parentNode;
        } else if (formItem.length) { // if this form item has length, that means it's a radio group, or checkbox group
            if (formItem[0].parentNode) {    // we just return the first item's parent in this group
                return formItem[0].parentNode;
            }
        }
    }
    return false;
}

/** Returns wrpper element of current form item. A wrapper is the first SPAN tag which current form item is in. */
function getWrapper(formItem) {
    var wrapper = getParentNode(formItem);
    while (wrapper && (wrapper.nodeName != "SPAN"))
        wrapper = wrapper.parentNode;
    return wrapper;
}

/** answer element is the first SPAN after the form item's parent, this element should exist all the time */
function getAnswerElement(formItem) {
    var parent = getWrapper(formItem);
    if (parent) {
        var answerElement = parent.nextSibling;
        // if it's not a SPAN, try next sibling
        while (answerElement && ( answerElement.nodeName != "SPAN")) {
            answerElement = answerElement.nextSibling;
        }
        return answerElement;
    }
    return false;
}

/** right element is a DIV tag with ID begins with correct_, after answer element's parent */
function getElementWhenAnswerIsRight(answerElement) {
    if (answerElement) {
        var parent = answerElement.parentNode;
        var rightElement = parent.nextSibling;
        while (rightElement && ( (rightElement.nodeName != "DIV") || (rightElement.id.indexOf("correct_") != 0) )) {
            rightElement = rightElement.nextSibling;
        }
        return rightElement;
    }
    return false;
}

/** wrong element is a DIV tag with ID begins with incorrect_, after answer element's parent */
function getElementWhenAnswerIsWrong(answerElement) {
    if (answerElement) {
        var parent = answerElement.parentNode;
        var wrongElement = parent.nextSibling;
        while (wrongElement && ((wrongElement.nodeName != "DIV") || (wrongElement.id.indexOf("incorrect_") != 0))) {
            wrongElement = wrongElement.nextSibling;
        }
        return wrongElement;
    }
    return false;
}

/** image element is the previous DIV before the form item's parent.
 also the first child of image element is a IMG element. */
function getImgDiv(formItem) {
    var parent = getWrapper(formItem);
    if (parent) {
        var imgDiv = parent.previousSibling;
        while (imgDiv && (imgDiv.nodeName != "DIV" || !imgDiv.firstChild || imgDiv.firstChild.nodeName != "IMG" )) {
            imgDiv = imgDiv.previousSibling;
        }
        if (!imgDiv) {
            // if can not find image div, try one upper level
            parent = parent.parentNode;
            imgDiv = parent.previousSibling;
            while (imgDiv && (imgDiv.nodeName != "DIV" || !imgDiv.firstChild || imgDiv.firstChild.nodeName != "IMG" )) {
                imgDiv = imgDiv.previousSibling;
            }
        }
        return imgDiv;
    }
    return false;
}

/**
 * Changes characters' expression
 *
 * imgDiv: the div tag for all characters' image
 * expression: the expression should be changed to
 */
function changeExpression(imgDiv, expression) {
    if (imgDiv) {
        for (var i = 0; i < imgDiv.childNodes.length; i++) {
            img = imgDiv.childNodes[i];
            if (img && (img.nodeName == "IMG")) {
                oldSrc = img.src;
                var ii = oldSrc.lastIndexOf(".");
                var filename = oldSrc.substring(0, ii);
                if (filename.substring(filename.length - 6, filename.length - 5) == '_')
                    filename = filename.substring(0, filename.length - 6);
                // if expression has value (right or wrong), display right or wrong expression
                if (expression != "")
                    newSrc = filename + "_" + expression + oldSrc.substring(ii);
                else // other wise, display normal expression
                    newSrc = filename + oldSrc.substring(ii);
                img.src = newSrc;
            }
        }
    }
}

/** check if answer is right */
function rightAnswer(formItem, num, answer) {
    var theForm = getForm(formItem);
    if (theForm) {
        var userInput = getElementValue(theForm.elements["q" + num]);
        // get rid of leading and trailing spaces
        userInput = trimString(userInput);
        // replace 2 spaces with 1 space
        while (userInput.indexOf("  ") != -1)
            userInput = userInput.replace("  ", " ");
        var answers = answer.split("*");
        var rightAnswers = answers[num].split("^");
        for (var i = 0; i < rightAnswers.length; i++) {
            if (userInput == rightAnswers[i])
                return true;
        }
    }
    return false;
}

/** Trims leading and trailing spaces */
function trimString(sInString) {
    // strip leading
    sInString = sInString.replace(/^\s+/g, "");
    // strip trailing
    return sInString.replace(/\s+$/g, "");
}

/** Checks if an element is empty or not */
function isEmpty(element) {
    if (!element)
        return true;
    if (!element.firstChild)
        return true;
    if (element.firstChild.nodeType == "Text") {
        var value = trimString(element.firstChild.nodeValue);
        if (value == "")
            return true;
    }
    return false;
}

function debug(element) {
    if (element) {
        alert(element);
        alert("node name = " + element.nodeName);
        if (element.getAttribute)
            alert("whoknows = " + element.getAttribute("whoknows"));
        else
            alert("whoknows is null");

    } else {
        alert("element is null");
    }
}


/**
 Check if answer is right and display reply instantly.
 Not use this any more.

 Param:
 formItem:   form element to input answer
 num:        which question
 answer:     '*' separated answer string
 */
function checkAndReply(formItem, num, answer) {
    var answerElement = getAnswerElement(formItem);
    var rightElement = getElementWhenAnswerIsRight(answerElement);
    var wrongElement = getElementWhenAnswerIsWrong(answerElement);
    var imgDiv = getImgDiv(formItem);
    if (check(formItem, num, answer)) {
        // display right reply information
        if (!isEmpty(rightElement))
            rightElement.style.display = "";
        if (!isEmpty(wrongElement))
            wrongElement.style.display = "none";
        changeExpression(imgDiv, "right");
    } else {
        // display wrong reply information
        if (!isEmpty(rightElement))
            rightElement.style.display = "none";
        if (!isEmpty(wrongElement))
            wrongElement.style.display = "";
        changeExpression(imgDiv, "wrong");
    }
}










