Source: units.js

(
/**
* Contains the functionalities related to the units page.
*
* @module units
* @author Joonas Konki
* @author Anu Koskela
* @author Mikko Kuhno
* @author Henrik Paananen
* @author Atte Räty
* @license BSD 3-clause, see LICENSE for more details.
* @copyright 2015 Kepler project authors
*/
function(){

var units = null; //List of units received from database
var emptyUnit = null;
var currentUnit = null;
var currentUnitId = null; //Used for if statements when currentUnit is undefined
var resources = null; //List of all available resources received from database.
// A copy of var resources that doesn't include the resources
// that the currentUnit has
var resCopy = null;
var currentRes = null;
var currentResId = null; //Used for if statements when currentRes is undefined

/**
* Sets the count for the selected resource.
* @memberof module:units
* @param {object} res - The selected resource.
* @returns A function which sets the count for the selected resource.
*/
function makeUpdateResource(res){
    return function () {
    //TODO (Anu) Checking of the input's format?
        res.count = parseInt($(this).val());
    };
}

/**
* Creates a label and an input field for the resource and fills them with the
* information of the resource.
* @memberof module:units
* @param {object} res - The resource to be shown.
*/
function addResourceToUnitInfo(res) {
    var resDiv = $("<div>").addClass("col-sm-12 form-horizontal");
    resDiv.attr("align", "left").css("clear", "both");

    var resLabel = $("<label>").addClass("control-label col-sm-4");
    resLabel.text(res.name).css("text-align", "left");

    var resQuantity = $("<input>").addClass("form-control quantity-input");
    resQuantity.attr("type", "number").attr("min", "0").val(res.count);

    resQuantity.change(makeUpdateResource(res));

    var resQuantityDiv = $("<div>").addClass("col-sm-3");
    resQuantityDiv.css("clear", "right").css("padding", "0px");

    resQuantityDiv.append(resQuantity);
    resDiv.append(resQuantityDiv);
    resDiv.append(resLabel);
    $("#resources").append(resDiv);
    $("#resWarning").hide();
}

/**
* Displays the current unit's resources and their amounts in the displayed
* resources area.
* @memberof module:units
*/
function updateResources(unit) {
    $("#resources").empty();
    $("#resources").show();
    if (unit.resources.length === 0) {
        $("#resWarning").show();
    }
    else {
        for (var i = 0; i < unit.resources.length; i++) {
            addResourceToUnitInfo(unit.resources[i]);
        }
    }
}

/**
* Sets the information of the chosen unit to the corresponding fields.
* @memberof module:units
*/
function setCurrentSelection(){
    var unit = currentUnit;

    for (var i = 0; i < unit.name_desc.length; i++) {
        if (unit.name_desc[i].locale === "fi") {
            $("#unitNameFi").val(unit.name_desc[i].name);
            $("#unitDescrFi").val(unit.name_desc[i].description);
        }
        if (unit.name_desc[i].locale === "en") {
            $("#unitNameEn").val(unit.name_desc[i].name);
            $("#unitDescrEn").val(unit.name_desc[i].description);
        }
    }
    $("#maxParticipants").val(unit.max_user_group_size);
    updateResources(unit);
}

/**
* Fills the unit list with the units that match the search string.
* @memberof module:units
* @param {string} inputText - String that has to be found in the name of every
* displayed unit.
*/
function updateUnitList(inputText){
    $("#unitList").empty();
    var filter = inputText.toLowerCase();
    for (var i = 0; i < units.length; i++) {
        var unit = units[i];
        var displayName = unit.name;
        var displayLower = displayName.toLowerCase();
        if (displayLower.indexOf(filter) != -1) {
            var option = $("<option>");
            option.val(unit.id);
            option.text(displayName);
            $("#unitList").append(option);
        }
    }
}

/**
* Makes a new object by cloning the empty unit received from the database.
* @memberof module:units
*/
function setNewUnit() {
    currentUnit = kepler.clone(emptyUnit);
    currentUnitId = currentUnit.id;
    setCurrentSelection();
}

/**
* Copies the list of resources and for each resource sets hidden to false if the
* current unit already uses the resource.
* @memberof module:units
*/
function setResCopy() {
    if(currentUnit === null) {return;}

    if(currentUnit.resources.length === 0) {
        for(var i in resCopy){
            resCopy[i].hidden = false;
        }
    }

    else {
        for (var k = 0; k < resCopy.length; k++) {
            resCopy[k].hidden = false;

            for (var j = 0; j < currentUnit.resources.length; j++) {
                if(resCopy[k].id === currentUnit.resources[j].id) {
                    resCopy[k].hidden = true;
                    break;
                }
            }
        }
    }
}

/**
* Empties the edit fields of the unit and reloads the current unit list.
* @memberof module:units
*/
function resetView() {
    $("#unitNameFi").val("").removeAttr("placeholder");
    $("#unitNameEn").val("").removeAttr("placeholder");
    $("#unitDescrFi").val("").removeAttr("placeholder");
    $("#unitDescrEn").val("").removeAttr("placeholder");
    $("#unitList").empty();
    $("#resources").empty();
    $("#resources").hide();
    unitList.load();
    $("#noSelectedUnit").show();
    $("#editFields").hide();
}

/**
* Displays all the resources in the list of resources that match the search
* criterion.
* @memberof module:units
* @param {string} inputText - The string that has to be found in the
* resource's name.
*/
function updateResList(inputText){
    $("#resourceList").empty();
    var filter = inputText.toLowerCase();
    for (var i = 0; i < resCopy.length; i++) {
        var res = resCopy[i];

        if(res.hidden) {continue;}

        var displayName = res.name;
        var displayLower = displayName.toLowerCase();

        if (displayLower.indexOf(filter) != -1) {
            var option = $("<option>");
            option.val(res.id);
            option.text(displayName);
            $("#resourceList").append(option);
        }
    }
}

/**
* If a resource has been selected, sets its information to the corresponding
* fields. Otherwise shows a notification.
* @memberof module:units
*/
function updateResInfo() {
    if (currentRes === null){
        $("#noResSelection").show();
        $("#resInfo").hide();
    }
    else {
        $("#resName").text(currentRes.name);

        if (currentRes.description === null) {
            $("#resDescr").text(kepler.translate('content.unit_no_descr'));
        }
        else {
            $("#resDescr").text(currentRes.description);
        }
        $("#resTotalQuantity").text(currentRes.total_count);
        $("#resQuantity").val("1");
    }
}

/**
* Initialises the modal where the resources are selected.
* @memberof module:units
*/
function initModal() {
    currentRes = null;
    currentResId = null;
    $("#resSearchField").val("");
    if(currentUnit !== null) {
        setResCopy();
        updateResList("");
        updateResInfo();
    }
}

/**
* Sets hidden to true for the current resource to prevent the resource
* from being displayed in the module.
* @memberof module:units
*/
function hideResource() {
    resCopy[currentRes.index].hidden = true;
}

/**
* Empties the edit fields and fills them with the information of the
* current unit, if the information can be found.
* Otherwise shows the placeholders.
* @memberof module:units
*/
function fillEditFields(){
    $("#noSelectedUnit").hide();
    $("#editFields").show();
    $("#unitNameFi").val("").attr("placeholder", "Anna työlle nimi.");
    $("#unitNameEn").val("").attr("placeholder",
                                  "Give a name to the experiment.");
    $("#unitDescrFi").val("").attr("placeholder",
                                   "Anna tarkempia tietoja työstä.");
    $("#unitDescrEn").val("").attr("placeholder",
        "Give more detailed information about the experiment.");
    setCurrentSelection();
    setResCopy();
}

/**
* This is executed after the HTML page has been loaded.
* This is a common procedure of all of the client-side modules to
* initialise the page content.
* @memberof module:units
*/
function doc_ready(){
    //Highlight the corresponding navigation area.
    $("#navUnits").addClass("active");

    $("#resources").hide();

    unitList = kepler.createLoadElement("#unitList", function (element) {
        call = kepler.getUnitsEditable(function(data) {
            var unitList = $("#unitList");
            units = data.units;
            emptyUnit = data.empty_unit;
            resources = data.resources;
            resCopy = kepler.clone(resources);
            for (var i = 0; i < units.length; i++) {
                var unit = units[i];
                var opt = $('<option>');
                opt.val(unit.id).text(unit.name);
                element.append(opt);
            }
            initModal();
            if(currentUnit === null && currentUnitId !== null) {
                for (var k = 0; k < units.length; k++){
                    if (units[k].id === currentUnitId) {
                        currentUnit = units[k];
                        fillEditFields();
                        break;
                    }
                }
            }
            if(currentUnit !== null) {
                $('#unitList option[value="' +
                currentUnitId + '"]').prop("selected", true);
            }
        });
        return call;
    });
    unitList.load();

    $("#searchField").on("input", function(v){
        var inputText = v.target.value;
        updateUnitList(inputText);
    });

    /**
    * Empties the edit fields and sets the placeholders.
    * Sets the current unit to null. Initialises the resource area.
    *
    * @function
    * @name btnAddNewUnit click
    * @inner
    * @memberof module:units
    */
    $("#btnAddNewUnit").click(function() {
        $("#noSelectedUnit").hide();
        $("#editFields").show();
        $("#unitNameFi").val("").attr("placeholder", "Anna työlle nimi.");
        $("#unitNameEn").val("").attr("placeholder",
                                      "Give a name to the experiment.");
        $("#unitDescrFi").val("").attr("placeholder",
                                       "Anna tarkempia tietoja työstä.");
        $("#unitDescrEn").val("").attr("placeholder",
            "Give more detailed information about the experiment.");
        currentUnit = null;
        currentUnitId = null;
        $("option:selected").prop("selected", false);
        setNewUnit();
    });

    /**
    * Makes a clone of the selected unit and sets its information to the
    * edit fields.
    *
    * @function
    * @name unitList change
    * @inner
    * @memberof module:units
    */
    $("#unitList").change(function (v) {
        if (currentUnitId !== v.target.value && v.target.value !== "") {
            for (var i = 0; i < units.length; i++) {
                if (units[i].id === parseInt(v.target.value)){
                    currentUnit = kepler.clone(units[i]);
                    currentUnitId = units[i].id;
                }
            }
            fillEditFields();
        }
    });

    /**
    * If current unit id is null, makes a call to create a new unit with the
    * given parameters. Otherwise makes a call to save changes to the current
    * unit. If important fields are empty, shows a notification without making
    * a call. Updates the view after the call has been completed.
    *
    * @function
    * @name btnSaveChanges click
    * @inner
    * @memberof module:units
    */
    $("#btnSaveChanges").click(function() {
        if(currentUnitId === null) {
            alert(kepler.translate('content.units_select_or_new_work') + "!");
            //TODO (Anu) Don't use alert!
        }
        else if (currentUnit.id !== -1) {
            var params = {
                "name_fi": $("#unitNameFi").val(),
                "name_en": $("#unitNameEn").val(),
                "description_fi": $("#unitDescrFi").val(),
                "description_en": $("#unitDescrEn").val(),
                "max_user_group_size": $("#maxParticipants").val(),
                "unit_id": currentUnitId,
                "resources": currentUnit.resources,
            };
            console.log(params);
            kepler.editUnit(
                params,
                function(data) {
                    kepler.showResult(data.result, "#notification");
                    currentUnit = null;
                    resetView();
                }
            );
        }
        else {
            if($("#unitNameFi").val() === "" && $("#unitNameEn").val() === ""){
                alert(kepler.translate('content.units_give_name') + "!");
                //TODO (Anu) Don't use an alert!
                return;
            }
            else {
                var params = {
                    "name_fi": $("#unitNameFi").val(),
                    "name_en": $("#unitNameEn").val(),
                    "description_fi": $("#unitDescrFi").val(),
                    "description_en": $("#unitDescrEn").val(),
                    "max_user_group_size": $("#maxParticipants").val(),
                    "resources": currentUnit.resources,
                };
                console.log("Tehdään uutta työtä. Parametrit ovat:");
                console.log(params);
                //TODO (Anu) Remove console.log when not needed anymore!
                kepler.addUnit(
                    params,
                    function(data) {
                        kepler.showResult(data.result, "#notification");
                        currentUnitId = data.result.unit_id;
                        currentUnit = null;
                        resetView();
                    }
                );
            }
        }
    });

    /**
    * If the current unit id is not null, removes it from the database.
    *
    * @function
    * @name btnDeleteUnit click
    * @inner
    * @memberof module:units
    */
    $("#btnDeleteUnit").click(function() {
        if(currentUnitId === null) {
            alert(kepler.translate('content.new_reservations_no_selected_unit')+
                "."); // TODO Don't use an alert
        }
        else {
            $("#modalButtonYes").off();
            /**
            * Makes a call to remove the current unit from the database.
            *
            * @function
            * @name modalButtonYes click
            * @inner
            * @memberof module:units
            */
            $("#modalButtonYes").click(function () {
                if (currentUnit.id === -1) {
                    currentUnit = null;
                    currentUnitId = null;
                    resetView();
                }
                else {
                    kepler.deleteUnit(
                        { "unit_id": currentUnitId },
                        function(data) {
                            kepler.showResult(data.result, "#notification");
                            currentUnit = null;
                            currentUnitId = null;
                            resetView();
                        }
                    );
                }
            });
            $("#modalLabel").text(currentUnit.name);
            $("#modalCancel").modal('show');
        }
    });

    $("#btnAddResource").click(function() {
        $("#modalResource").modal('show');
        initModal();
    });

    $("#resSearchField").on("input", function(v) {
        var inputText = v.target.value;
        updateResList(inputText);
    });

    /**
    * Displays the information of the selected resource.
    *
    * @function
    * @name resourceList change
    * @inner
    * @memberof module:units
    */
    $("#resourceList").change(function (v) {
        $("#noResSelection").hide();
        $("#resInfo").show();
        if (currentResId !== v.target.value && v.target.value !== "") {
            var selectedId = parseInt(v.target.value);
            for (var i = 0; i < resources.length; i++) {
                if (resources[i].id === selectedId){
                    currentRes = resources[i];
                    currentResId = resources[i].id;
                    currentRes.index = i;
                    break;
                }
            }
            updateResInfo();
        }
    });

    /**
    * Adds the selected resource to the list of resources of the current
    * unit and updates the view.
    *
    * @function
    * @name modalButtonAdd click
    * @inner
    * @memberof module:units
    */
    $("#modalButtonAdd").click(function() {
        currentRes.count = parseInt($("#resQuantity").val());
        currentUnit.resources.push(currentRes);
        $("#modalResource").modal('hide');
        addResourceToUnitInfo(currentRes);
        hideResource();
    });

    $("#modalButtonCancel").click(function() {
        $("#modalResource").modal('hide');
    });

}

$(document).ready(doc_ready);
}());