﻿////////////////////////////////////////////////////////////////
//  PLManager.js                                              //
//  Page Lock Manager handles html page locking feature       //  
//  based on the page visits and assesment results criteria.  //
//  Author: sudhir murthy, mailto: sudhirm@contentmaster.com  //
//  Copyright(c) CM Group. 2009.                              //
////////////////////////////////////////////////////////////////


//AssementResults object is used
//to save the completed assements
//associated with a page guid.
AssesmentResults = function() {
    this.Guid = null;
    this.Passmark = null;
}

//PageLockData object is used to
//hold page lock metadata defined
//in the course.
//@navItem - the navItem associated with this page lock data.
//@lockedpageGuid - the guid of the locked page.
//@pagesToComplete - the guids of the pages to be completed before unlocking.
//@assesmentResultsToComplete - a list of assements to complete before unlocking.
//@flagCompleted - flag to indicate if the page is unlock worthy.
//@flagAssesmentsComplete - flag to indicate if the assement criteria is met.
//@flagPageVistsComplete - flag to indicate if the page visits criteria is met.
PageLockData = function() {
    this.navItem = null;
    this.pagesToComplete = new Array();
    this.assesmentResultsToComplete = new Array();
    this.flagCompleted = false;
    this.flagPagesComplete = false;
    this.flagAssesmentsComplete = false;
}

if (!window.PLManager)
    window.PLManager = {};

PLManager.PageLocking = function() {      
    //an array of pageLockData.
    this.lockedItems = new Array();    
}

PLManager.PageLocking.prototype = {

    //Initializes pageunlock information for every page with page
    //lock. All other pages without page locks are ignored.
    //assesmentResultsToComplete[i].Guid
    //assesmentResultsToComplete[i].Passmark
    InitPageLockData: function(navItem, unlockItems, unlockAssementMarks) {

        var lockData = new PageLockData();
        lockData.navItem = navItem;
        navItem.SetState(3);

        if (unlockItems.length >= 1) {
            lockData.pagesToComplete = unlockItems;
        }
        else {
            lockData.flagPagesComplete = true;
        }

        if (unlockAssementMarks.length >= 1) {
            lockData.assesmentResultsToComplete = unlockAssementMarks;
        }
        else {
            lockData.flagAssesmentsComplete = true;
        }

        this.lockedItems.push(lockData);

    },

    GetNavItemwithGUID: function(guid) {

        for (var i = 0; i < navItems.length; i++) {
            if (navItems[i].guid == guid) {
                return navItems[i];
            }
        }

        return null;
    },

    ReinitilaizeLockedNavItems: function() {
        for (var i = 0; i < this.lockedItems.length; i++) {
            var navguids = new Array();
            var navs = new Array();

            navguids = this.lockedItems[i].pagesToComplete;

            for (var j = 0; j < navguids.length; j++) {
                var item = this.GetNavItemwithGUID(navguids[j]);
                if (item != null) {
                    navs.push(this.GetNavItemwithGUID(navguids[j]));
                }
            }

            this.lockedItems[i].pagesToComplete = navs;
        }
    },

    //SubsetArray
    //params: @sArray - Source Array, @tArray - Test Array
    //SubsetArray returns true if all the elements in the Test Array
    //are present in the SourceArray i.e Test Array is a subset of Source Array,
    //else it returns false.  
    SubsetArray: function(sArray, tArray) {
        for (var i = 0; i < tArray.length; i++) {
            if (sArray.Contains(tArray[i])) {
                if (i == tArray.length - 1) {
                    return true;
                }
                continue;
            }
            else {
                return false;
            }
        }
    },

    //CheckAssesmentsFinished
    //params: @sArray - Source Array, @tArray - Test Array
    //CheckAssesmentsFinished returns true if all the elements in the Test Array 
    //object's Guid matches the SourceArray object's Guid and if the passmark for that
    //GUID is greater than or equal to the passmark required to unlock the page, else it returns false.
    CheckAssesmentsFinished: function(sArray, tArray) {

        var flagPassComplete = false;
        var sourceArray = new Array();
        var testArray = new Array();

        for (var i = 0; i < sArray.length; i++) {
            sourceArray.push(sArray[i].Guid);
        }
        for (var j = 0; j < tArray.length; j++) {
            testArray.push(tArray[j].Guid);
        }

        if (this.SubsetArray(sourceArray, testArray)) {
            //Assesment completed.

            //Total no. of assements to pass.
            var passCount = (tArray.length);

            for (var u = 0; u < sArray.length; u++) {
                for (var v = 0; v < tArray.length; v++) {
                    if (sArray[u].Guid == tArray[v].Guid) {
                        if (sArray[u].Passmark >= tArray[v].Passmark) {
                            passCount--;
                        }
                    }
                }
            }

            //Assesment completed and passmark achieved.
            if (passCount == 0) {
                flagPassComplete = true;
            }
            //Assesment completed but failed to achieve passmark.
            //TODO: Display dialog msg - Assesments failed, minimum pass percentage is lower
            //than the required criteria for this page to be unlocked.
            else {
                flagPassComplete = false;
            }

        }
        else {
            //Assesment not completed.
            //TODO: Display dialog msg - Assesments should be completed for this page to be
            //unlocked.
            flagPassComplete = false;
        }

        return flagPassComplete;
    },

    GetListNavItemGuids: function(navItemArray) {
        var guidList = new Array();

        for (var i = 0; i < navItemArray.length; i++) {
            if (navItemArray[i].guid != null) {
                guidList.push(navItemArray[i].guid);
            }
        }

        return guidList;
    },

    CheckPageCompletion: function(lockedItem, completedNavItems) {

        var lockedguids = this.GetListNavItemGuids(lockedItem.pagesToComplete);
        var cmpltdguids = this.GetListNavItemGuids(completedNavItems);

        if (lockedguids != null && cmpltdguids != null) {
            if (this.SubsetArray(cmpltdguids, lockedguids)) {
                return true;
            }
            else {
                return false;
            }
        }
        return false;
    },

    CheckAsmtsCompletion: function(lockedItem, completedAsmts) {

        var listasmtsResults = new Array();

        for (var i = 0; i < completedAsmts.length; i++) {
            var assmts = new AssesmentResults();
            assmts.Passmark = completedAsmts[i].score;
            assmts.Guid = completedAsmts[i].navItem.guid;
            listasmtsResults.push(assmts);
        }

        return this.CheckAssesmentsFinished(listasmtsResults, lockedItem.assesmentResultsToComplete);

    },

    //check page visits criteria required for the page to be unlocked.
    //if page visits are sufficient for the page to be unlocked, then unlock the page.
    //else don't bother unlocking the page.
    CheckUnlockCriteria: function(completednavItems, completedAsmts) {

        var unlockedItems = new Array();

        for (var i = 0; i < this.lockedItems.length; i++) {

            if (!this.lockedItems[i].flagCompleted) {

                if (!this.lockedItems[i].flagPagesComplete) {
                    if (this.CheckPageCompletion(this.lockedItems[i], completednavItems)) {
                        this.lockedItems[i].flagPagesComplete = true;
                    }
                }

                if (!this.lockedItems[i].flagAssesmentsComplete) {
                    if (this.CheckAsmtsCompletion(this.lockedItems[i], completedAsmts)) {
                        this.lockedItems[i].flagAssesmentsComplete = true;
                    }
                }

                if (this.lockedItems[i].flagPagesComplete &&
                   this.lockedItems[i].flagAssesmentsComplete) {
                    this.lockedItems[i].flagCompleted = true;
                    unlockedItems.push(this.lockedItems[i].navItem);
                }
            }
        }

        if (unlockedItems.length > 0) {
            return unlockedItems;
        }
        else {
            return null;
        }
    },

    //Gets a list of NavItems to be unlocked for the
    //passed in @navItem.
    GetNavItemstobeUnlocked: function(navItem) {
        var nitems = new Array();

        var pages = new Array();
        var assts = new Array();

        for (var i = 0; i < this.lockedItems.length; i++) {
            if (this.lockedItems[i].navItem.guid == navItem.guid) {
                pages = this.lockedItems[i].pagesToComplete;
                break;
            }
        }

        for (var j = 0; j < pages.length; j++) {
            for (var k = 0; k < navItems.length; k++) {
                if (pages[j].guid == navItems[k].guid) {
                    nitems.push(navItems[k]);
                }
            }
        }

        for (var u = 0; u < this.lockedItems.length; u++) {
            if (this.lockedItems[u].navItem.guid == navItem.guid) {
                assts = this.lockedItems[u].assesmentResultsToComplete;
                break;
            }
        }

        for (var m = 0; m < assts.length; m++) {
            for (var n = 0; n < navItems.length; n++) {
                if (assts[m].Guid == navItems[n].guid) {
                    nitems.push(navItems[n]);
                }
            }
        }

        return nitems;
    }

}