﻿/*
Client-side initialization and event handlers of CUVocalWeb
*/


/***** Page Initialization *****/

function pageLoad() {
    //embed the flash mediaplayer
    if (swfobject) {

        //Create the MediaPlayer control.
        var properties = {
            swf: "assets/mediaplayer/mediaplayer.swf",
            flashId: "mediaplayer",
            width: "550",
            height: "20",
            params: {
                allowfullscreen: "true",
                allowscriptaccess: "always"
            },
            flashvars: {
                width: "550",
                height: "20",
                config: "assets/mediaplayer/config.xml"
            }
        };
        $create(CUVocalWeb.MediaPlayer, properties, null, null, $get("mediaplayer"));

        $get("mediaplayer").style.display = "block";
    }

    //get global resources
    var resourceNames = [
        "synthesizing",
        "requestFailed",
        "responseInvalid",
        "wordsCountingHint"
    ];
    for (var tipId in CUVocalWeb.Tips) {
        resourceNames.push(tipId + "Tip");
    }
    PageMethods.GetGlobalResources(resourceNames, CUVocalWeb.onGetGlobalResourcesSucceeded);

    //initialize the content of textarea
    $get("synText").value = CUVocalWeb.OriginalText;

    //add event handlers
    for (var tipId in CUVocalWeb.Tips) {
        $addHandlers($get(tipId), { mouseover: CUVocalWeb.onTipsShowing, mouseout: CUVocalWeb.onTipsRestoring }, CUVocalWeb);
    }
    $addHandlers($get("reset"), { click: CUVocalWeb.onResetClicking }, CUVocalWeb);
    $addHandlers($get("clear"), { click: CUVocalWeb.onClearClicking }, CUVocalWeb);
    $addHandlers($get("synText"), { focus: CUVocalWeb.onWordsCounting, keyup: CUVocalWeb.onWordsCounting }, CUVocalWeb);
    $addHandlers($get("synthesize"), { click: CUVocalWeb.onSynthesizeClicking }, CUVocalWeb);
}


Type.registerNamespace("CUVocalWeb");


/***** Properties *****/

CUVocalWeb.Tips = {
    speakingRate: "",
    synthesize: "",
    reset: "",
    clear: ""
}

CUVocalWeb.OriginalText = "歡迎試用 CU Vocal 中文大學「悠揚」語音合成系統。\n\n"
                        + "請先在此輸入文字，然後按「閱讀」按鈕及聆聽結果。\n\n"
                        + "如有任何查詢或意見，請電郵至 hmmeng@se.cuhk.edu.hk。\n\n"
                        + "「悠揚」是香港中文大學人機通訊實驗室的科研成果。\n\n"
                        + "英文語音技術是由 Microsoft Corporation 提供。";

CUVocalWeb.LastTips = "";


/***** Event Handlers *****/

CUVocalWeb.onTipsShowing = function(e) {
    if (this.Tips[e.target.id]) {
        $get("tips").innerHTML = this.Tips[e.target.id];
    }
}

CUVocalWeb.onTipsRestoring = function(e) {
    $get("tips").innerHTML = this.LastTips;
}

CUVocalWeb.onResetClicking = function(e) {
    $get("synText").value = this.OriginalText;
    this.validateText();
}

CUVocalWeb.onClearClicking = function(e) {
    $get("synText").value = "";
    this.validateText();
}

CUVocalWeb.onWordsCounting = function(e) {
    this.validateText();
}

CUVocalWeb.onSynthesizeClicking = function(e) {
    $find("mediaplayer").sendEvent("stop");

    if (!this.validateText()) {
        return;
    }
    var content = $get("synText").value;
    var speakingRate = $get("speakingRate");
    var speed = speakingRate.options[speakingRate.selectedIndex].value;

    $get("synText").disabled = "disabled";
    this.showTips(CUVocalWeb.GlobalResources["synthesizing"]);

    var params = {
        action: "synthesize",
        content: content,
        speed: speed,
        response: "json"
    };
    var paramsQuery = this.serializeParams(params);

    var request = new Sys.Net.WebRequest();
    request.set_url("cuvocal.api");
    request.set_httpVerb("POST");
    request.add_completed(Type.createDelegate(CUVocalWeb, this.onSynthesizeCallback));
    request.set_body(paramsQuery);
    request.get_headers()["Content-Length"] = paramsQuery.length;
    request.invoke();
}

/***** Ajax Callback *****/

CUVocalWeb.onSynthesizeCallback = function(executor, eventArgs) {
    $get("synText").disabled = "";

    if (!executor.get_responseAvailable()) {
        this.showTips(CUVocalWeb.GlobalResources["requestFailed"]);
        return;
    }

    try {

        var result = eval("(" + executor.get_responseData() + ")");

    } catch (ex) {
        this.showTips(CUVocalWeb.GlobalResources["responseInvalid"]);
        return;
    }

    if (result.FileName && result.Path) {
        var flashvars;
        if (result.Path.indexOf("http://") < 0) {
            flashvars = {
                file: result.Path,
                id: result.FileName
            }
        } else {
            flashvars = {
                file: result.Path + result.FileName
            }
        }
        var player = $find("mediaplayer");
        player.loadFile(flashvars);
    }

    this.showTips(result.Message);
}

CUVocalWeb.onGetGlobalResourcesSucceeded = function(result) {
    if (!result) {
        return;
    }

    CUVocalWeb.GlobalResources = result;

    //set localized hints
    for (var tipId in CUVocalWeb.Tips) {
        CUVocalWeb.Tips[tipId] = CUVocalWeb.GlobalResources[tipId + "Tip"];
    }
}

/***** Helper Methods *****/

CUVocalWeb.showTips = function(message) {
    this.LastTips = message;
    $get("tips").innerHTML = this.LastTips;
}

CUVocalWeb.hideTips = function() {
    $get("tips").innerHTML = "";
}

CUVocalWeb.validateText = function() {
    var length = $get("synText").value.replace(/\s/gi, "").length;
    var message, valid;

    if (length > 500 || length == 0) {
        message = String.format(CUVocalWeb.GlobalResources["wordsCountingHint"], "<span class=\"error\">" + length + "</span>");
        valid = false;
    } else {
    message = String.format(CUVocalWeb.GlobalResources["wordsCountingHint"], length);
        valid = true;
    }
    this.showTips(message);
    return valid;
}

CUVocalWeb.serializeParams = function(params) {
    var results = [];
    for (var name in params) {
        results.push(name + "=" + encodeURIComponent(params[name]));
    }
    return results.join("&");
}