﻿function InitializeUnicodeNepali() {
    SCM.setup({ 'preventDefault': true, 'preventForms': false });
    SCM.attach('UnicodeNepali', 'UnicodeNepaliMenu');
    var controlsToWireUp = GetAllUnicodeTextBoxes();
    for (var i = 0; i < controlsToWireUp.textareas.length; i++) {
        var textArea = controlsToWireUp.textareas[i];
        var unicodeControl = new UnicodeControl(textArea);
    }

    for (var i = 0; i < controlsToWireUp.textboxes.length; i++) {
        var textBox = controlsToWireUp.textboxes[i];
        var unicodeControl = new UnicodeControl(textBox);
    }

    window.onunload = function(e) {
        GetEngine().OnUnload();
    };

}

function GetAllUnicodeTextBoxes() {
    var textBoxesToWireUp = new Array();
    var textAreasToWireUp = new Array();

    var forms = document.forms;

    for (var i = 0; i < forms.length; i++) {
        for (var j = 0; j < forms[i].elements.length; j++) {
            var element = forms[i].elements[j];
            if (element.tagName == "TEXTAREA") {
                var classAttribute = GetElementAttribute(element, "class");
                if (classAttribute == "UnicodeNepali") {
                    textAreasToWireUp[textAreasToWireUp.length] = element;
                }

            }
            else if (element.tagName == "INPUT" && element.getAttribute("type").toLowerCase() == "text") {
                if (GetElementAttribute(element, "class") == "UnicodeNepali") {
                    textBoxesToWireUp[textBoxesToWireUp.length] = element;
                }
            }
        }
    }

    return { "textboxes": textBoxesToWireUp, "textareas": textAreasToWireUp };
}

function GetElementAttribute(element, attributeName) {
    if (!element || !attributeName || attributeName.length == 0)
        return "";

    for (var i = 0; i < element.attributes.length; i++) {
        if (element.attributes[i].nodeName == attributeName)
            return element.attributes[i].nodeValue;
    }

    return "";
}

function UnicodeControl(control) {
    if (!control.id || control.id.length == 0) {
        var controlUniqueID = "UnicodeNepaliControl_" + new Date().getMilliseconds();
        while (document.getElementById(controlUniqueID)) {
            controlUniqueID = "UnicodeNepaliControl_" + new Date().getMilliseconds();
        }

        control.id = controlUniqueID;
    }

    control.onclick = function(e) {
        OnClickHandler(e);
    };

    control.onkeyup = function(e) {
        OnKeyUpHandler(e);
    };

    control.onkeydown = function(e) {
        OnKeyDownHandler(e);
    };

    var parentDiv = control.parentNode;
    if (!parentDiv.id || parentDiv.id.length == 0) {
        var controlUniqueID = "UnicodeNepaliControl_Container" + new Date().getMilliseconds();
        while (document.getElementById(controlUniqueID)) {
            controlUniqueID = "UnicodeNepaliControl_Container" + new Date().getMilliseconds();
        }
        parentDiv.id = controlUniqueID;
    }

    if (!control.style.width || control.style.width.length == 0) {
        if (parentDiv.style.width && parentDiv.style.width.length > 0) {
            control.style.width = "100%";
        }
        else if (control.cols && control.cols > 0) {
            control.style.width = (control.cols * 10) + "px";
        }
    }

    parentDiv.style.width = "98%";

    if ((control.cols && control.cols == null) || control.style.width == null)
        control.style.width = "100%";

    if (control.tagName == "TEXTAREA") {
        globalIsAUnicodeTextAreaPresent = true;
    }
}

var globalIsAUnicodeTextAreaPresent = false;
var globalIsInUnicodeMode = true;
function OnKeyDownHandler(e) {
    var event = GetEvent(e);
    var keyCode = GetEnteredKeyCode(e);
    if (event.ctrlKey && keyCode == 85) {
        if (globalIsInUnicodeMode)
            globalIsInUnicodeMode = false;
        else
            globalIsInUnicodeMode = true;

        if (event.cancelBubble != null)
            event.cancelBubble = true;

        if (event.preventDefault)
            event.preventDefault();

        return false;
    }
}

function OnKeyUpHandler(e) {

    var event = GetEvent(e);
    var control = GetEventSource(event);
    var enteredKeyCode = GetEnteredKeyCode(event);

    var keyboardLayout = GetKeyboardLayout();
    var conversionMode = GetConversionMode();

    if (conversionMode == "Basic" && keyboardLayout != "Default") {
        var cursorAt = GetCursorPosition(control) - 1;

        var startAt = cursorAt;
        var endAt = cursorAt;

        var currentText = control.value;
        var enteredChar = currentText.charAt(startAt);
        var convertedChar = GetEngine().Convert(enteredChar);
        currentText = currentText.substring(0, startAt) + convertedChar + currentText.substring(endAt + 1);
        control.value = currentText;

        SelectWord(control, endAt + 1, endAt + 1);
    }
    else if (enteredKeyCode == 32 || enteredKeyCode == 13) {
        var cursorAt = GetCursorPosition(control) - 1;

        var startAt = GetStartIndex(control, cursorAt);
        var endAt = GetEndIndex(control, startAt + 1);

        var word = control.value.substring(startAt, endAt);
        var converted = GetEngine().Convert(word);

        control.value = control.value.substring(0, startAt)
            + converted + control.value.substring(endAt);

        var putCursorAt = startAt + converted.length + 1;
        if (enteredKeyCode == 13 && control.value.charCodeAt(control.value.length - 1) == 10) {
            putCursorAt += 2;
        }

        if (putCursorAt < control.value.length) {
            SelectWord(control, putCursorAt, putCursorAt);
        }
    }
}

var globalToggleMenuOnClick = "";
function OnClickHandler(e) {
    var conversionMode = GetConversionMode();

    if (conversionMode != "Smart") {
        SCM.hide(e);
        return false;
    }

    var event = GetEvent(e);
    var control = GetEventSource(event);
    var selectedText = GetSelectedText();
    if (selectedText && selectedText.indexOf(' ') > 0) {
        if (event.cancelBubble != null)
            event.cancelBubble = true;

        if (event.preventDefault)
            event.preventDefault();

        return false;
    }

    var cursorAt = GetCursorPosition(control);
    if (cursorAt == control.value.length) {
        SCM.hide(e);
        globalToggleMenuOnClick = "";
        return;
    }

    var startAt = GetStartIndex(control, cursorAt);
    var endAt = GetEndIndex(control, startAt + 1);

    var word = SelectWord(control, startAt, endAt);
    if (cursorAt == control.value.length || globalToggleMenuOnClick == word) {
        SCM.hide(e);
        globalToggleMenuOnClick = "";
        return;
    }

    globalToggleMenuOnClick = word;
    ShowMenu(control, word, e);
}

function GetSelectedText() {
    var text = '';
    if (window.getSelection) {
        text = window.getSelection();
    }
    else if (document.getSelection) {
        text = document.getSelection();
    }
    else if (document.selection) {
        text = document.selection.createRange().text;
    }
    return text.toString();
}


function GetEvent(e) {
    if (window.event) {
        return window.event;
    }
    else if (e) {
        return e;
    }
    return null;
}

function GetEventSource(e) {
    var event = GetEvent(e);
    if (event.explicitOriginalTarget)
        return event.explicitOriginalTarget;

    if (event.srcElement)
        return event.srcElement;

    return null;
}

function GetEnteredKeyCode(e) {
    var keyCode;
    if (window.event) {
        keyCode = window.event.keyCode;
    }
    else if (e) {
        keyCode = e.keyCode;
    }
    return keyCode;
}

function SelectWord(control, start, end) {
    if (control.setSelectionRange) {
        control.focus();
        control.setSelectionRange(start, end);
        return control.value.substring(start, end);
    }
    else if (control.createTextRange) {
        var lineBreaksCount = GetLineBreakCount(control, end);
        start -= lineBreaksCount;
        end -= lineBreaksCount;
        var range = control.createTextRange();
        range.collapse(true);
        range.moveEnd('character', end);
        range.moveStart('character', start);
        range.select();
        return range.text;
    }
}

function GetCursorPosition(control) {
    var len;
    if (control.selectionStart || control.selectionStart == '0') {
        len = control.selectionStart;
    }
    else if (document.selection) {
        control.focus();
        var c = "\001";
        var sel = document.selection.createRange();
        var dul = sel.duplicate();
        len = 0;
        try {
            dul.moveToElementText(control);
        }
        catch (err) {
            dul.expand('textedit');
        }

        sel.text = c;
        len = (dul.text.indexOf(c));
        sel.moveStart('character', -1);
        sel.text = "";
    }

    if (len < 0)
        len = control.value.length;

    return len;
}

function GetStartIndex(control, startPosition) {
    if (startPosition < 1)
        return 0;

    var text = control.value.toString();
    var thisChar = text.charAt(startPosition);

    while (startPosition > 0 && (!thisChar || thisChar == ' ' || thisChar == '\n' || thisChar == '\r')) {
        startPosition--;
        thisChar = text.charAt(startPosition);
    }

    var i = startPosition;
    thisChar = text.charAt(i);
    while (i > 0) {
        if (!thisChar || thisChar == ' ' || thisChar == '\n' || thisChar == '\r')
            break;
        i--;
        thisChar = text.charAt(i);
    }

    if (i > 0)
        i++;

    return i;

}

function GetEndIndex(control, startPosition) {
    var nextSpaceIndex = control.value.indexOf(' ', startPosition);
    var nextNewLineIndex = control.value.indexOf(String.fromCharCode(13), startPosition);
    if (nextNewLineIndex == -1)
        nextNewLineIndex = control.value.indexOf('\n', startPosition);

    if (nextNewLineIndex > -1 && ((nextSpaceIndex == -1) || (nextSpaceIndex > nextNewLineIndex)))
        nextSpaceIndex = nextNewLineIndex;

    if (nextSpaceIndex == -1)
        return control.value.length;
    else
        return nextSpaceIndex;
}

function GetLineBreakCount(control, endIndex) {
    var text = control.value;
    var lineBreakCount = 0;
    for (var i = 0; i < endIndex; i++) {
        if (text.charAt(i) == '\r')
            lineBreakCount++;
    }
    return lineBreakCount;
}

function ShowMenu(control, forWord, e) {
    var menuHtml = "";
    var controlReference = "getElementById('" + control.id + "')";
    var menuOptions = GetEngine().Suggest(forWord);
    var alreadyUsedOptions = new Object();
    for (i = 0; i < menuOptions.length; i++) {
        if (!alreadyUsedOptions[menuOptions[i]]) {
            menuHtml += "<li><a href=\"#\" onclick=\"return InsertAtCursor(" + controlReference + ", '" + forWord + "', this.innerHTML, event)\">" + menuOptions[i] + "</a></li>";
            alreadyUsedOptions[menuOptions[i]] = "true";
        }
    }

    var menu = document.getElementById("UnicodeNepaliMenu");
    menu.innerHTML = menuHtml;
    if (menuHtml.length > 0) {
        SCM.show(e);
    }
}

function InsertAtCursor(control, forWord, value) {
    var cursorAt = 0;
    if (document.selection) {
        control.focus();
        var sel = document.selection.createRange();
        sel.text = value;

        if (forWord && forWord.length > 0) {
            document.selection.clear();
            cursorAt = GetCursorPosition(control);
        }
    }
    else if (control.selectionStart || control.selectionStart == '0') {
        var startPos = control.selectionStart;
        var endPos = control.selectionEnd;
        control.value = control.value.substring(0, startPos) + value + control.value.substring(endPos, control.value.length);
        cursorAt = startPos;
    }
    else {
        control.value += value;
        cursorAt = value.length;
    }

    if (forWord && forWord.length > 0) {
        GetEngine().MarkUserCorrected(forWord, value);
        SCM.hide();

        var putCursorAt = cursorAt + value.length + 1;
        if (putCursorAt > control.value.length)
            putCursorAt = control.value.length;

        SelectWord(control, putCursorAt, putCursorAt);
    }

    return false;
}

function GetEffectiveWidth(control) {
    if (control.offsetWidth)
        return control.offsetWidth;

    var width = document.defaultView.getComputedStyle(control, "").getPropertyValue("width");
    width = width.split('px');
    return width[0];
}

var _PromptedForSilverlight = false;
function GetEngine() {
    try {
        var engineElement = document.getElementById("UNEngine");
        var content = engineElement.content;
        var engine = content.UNEngine;
        return engine;
    } catch (err) {
        if (!_PromptedForSilverlight)
        {
            alert("You need to install Microsoft Silverlight to use UnicodeNepali.com. To install, click on the 'Install Microsoft Silverlight' button below; OR you can use the old version of the Converter by clicking on one of the links below.");
            _PromptedForSilverlight = true;
        }
    }
}


var _ConversionMode;
function SetConversionMode() {
    var conversionModeControl = document.getElementById("conversionMode");
    var conversionMode = conversionModeControl.options[conversionModeControl.selectedIndex].value;
    var engine = GetEngine();
    engine.SetConversionMode(conversionMode);
    _ConversionMode = conversionMode;
}

function GetConversionMode() {
    if (!_ConversionMode) {
        var conversionModeControl = document.getElementById("conversionMode");
        _ConversionMode = conversionModeControl.options[conversionModeControl.selectedIndex].value;
    }
    return _ConversionMode;
}

var _ConversionModeSmart;
var _ConversionModeBasic;
var _ConversionModeNone;
function PopulateConversionModes(includeSmart) {
    var conversionModeControl = document.getElementById("conversionMode");

    if (!_ConversionModeSmart)
        _ConversionModeSmart = conversionModeControl.options[0];

    if (!_ConversionModeBasic)
        _ConversionModeBasic = conversionModeControl.options[1];

    if (!_ConversionModeNone)
        _ConversionModeNone = conversionModeControl.options[2];

    conversionModeControl.options.length = 0;

    if (includeSmart && includeSmart == true) {
        conversionModeControl.options[conversionModeControl.options.length] = _ConversionModeSmart;
    }
    else {
    }
    conversionModeControl.options[conversionModeControl.options.length] = _ConversionModeBasic;
    conversionModeControl.options[conversionModeControl.options.length] = _ConversionModeNone;
    conversionModeControl.selectedIndex = 0;
    SetConversionMode();
}

var _KeyboardLayout;
function SetKeyboardLayout() {
    var keyboardLayoutControl = document.getElementById("keyboardLayout");
    var keyboardLayout = keyboardLayoutControl.options[keyboardLayoutControl.selectedIndex].value;
    var engine = GetEngine();
    engine.SetKeyboardLayout(keyboardLayout);
    _KeyboardLayout = keyboardLayout;

    PopulateConversionModes(_KeyboardLayout == "Default");
}


function GetKeyboardLayout() {
    if (!_KeyboardLayout) {
        var keyboardLayoutControl = document.getElementById("keyboardLayout");
        var _KeyboardLayout = keyboardLayoutControl.options[keyboardLayoutControl.selectedIndex].value;
    }
    return _KeyboardLayout;
}
