LoginValidationTypes = {
    AnyChar:0,
    Alphanumeric:1,
    Numeric:2,
    Alphabetic:3,
    Email:4
};
QCKeys = {
    F12:0,
    CtrlF12:1,
    AltF12:2
};
Ext.define('LessonClass', {
    extend:'Ext.util.Observable',
    constructor:function (cfgXML, config) {
        Ext.apply(this, config);
        this.addEvents({
            "lessonInitialized":true,
            "lessonTimeout":true
        });
        this.callParent([]);
        this.Name = cfgXML.getAttribute('name');
        this.NameNoSpace = this.Name.replace(/\s/gi, '_');
        this.Width = XmlHelper.getIntegerAttribute(cfgXML, 'width');// parseInt(cfgXML.getAttribute('width'));
        this.Height = XmlHelper.getIntegerAttribute(cfgXML, 'height');  //parseInt(cfgXML.getAttribute('height'));
        this.Version = XmlHelper.getStringAttribute(cfgXML, 'version');//cfgXML.getAttribute('version');
        this.IsInitialized = false;
        this.LessonRoot = null;
        this.LessonNodes = new Ext.util.MixedCollection();
        this.StartTime = 0;
        this.InternalTimer = null;
        this.QCUrl = null;
        this.QCKey = QCKeys.F12;
        this.RequireLogin = false;
        this.LoginMessage = "";
        this.LoginPrompt = "";
        this.LoginLength = 0;
        this.LoginValidationType = LoginValidationTypes.AnyChar;
        this.PassMark = 100;
        this.RepeatLesson = false;
        this.IsTimeoutEnabled = false;
        this.Timeout = 0;
        this.SendWebResult = false;
        this.WebResultUrl = "";
        this.WebResultFields = "000000000";
        this.TimeoutTimer = null;
        this.browserBackgroundType = "COLOR";
        this.browserBackgroundImage = "";
        this.browserBackgroundColor = "#FFFFFF";
        this.browserBackgroundImageMode = "Scaled";
        this.UseCompletionAsScore = false;
        this.ShowReferenceButton = false;

        var preferenceNode = cfgXML.getElementsByTagName('lessonPreference')[0];
        if (preferenceNode) {
            this.PassMark = XmlHelper.getIntegerAttribute(preferenceNode, 'passmark');
            this.RepeatLesson = XmlHelper.getBooleanAttribute(preferenceNode, 'repeat');
            this.IsTimeoutEnabled = XmlHelper.getBooleanAttribute(preferenceNode, 'isTimeoutEnabled');
            this.UseCompletionAsScore = XmlHelper.getBooleanAttribute(preferenceNode, 'useCompletionAsScore');
            this.ShowReferenceButton = XmlHelper.getBooleanAttribute(preferenceNode, 'showReferenceButton');
            this.Timeout = XmlHelper.getIntegerAttribute(preferenceNode, 'timeout');
            var qcNode = preferenceNode.getElementsByTagName('qcNode')[0];
            if (qcNode) {
                this.QCUrl = XmlHelper.getStringAttribute(qcNode, "qcUrl");
                this.QCKey = XmlHelper.getIntegerAttribute(qcNode, "qcKey");
            }
            var loginNode = preferenceNode.getElementsByTagName('loginNode')[0];
            if (loginNode) {
                this.RequireLogin = XmlHelper.getBooleanAttribute(loginNode, 'requireLogin');
                if (this.RequireLogin) {
                    this.LoginLength = XmlHelper.getIntegerAttribute(loginNode, 'length');
                    this.LoginValidationType = XmlHelper.getIntegerAttribute(loginNode, 'validation');
                    this.LoginPrompt = XmlHelper.getStringAttribute(loginNode, 'prompt');
                    this.LoginMessage = XmlHelper.tryGetValue(preferenceNode, 'loginNode', TryGetValueOption.Normal, "");
                }
            }
            var webResultNode = preferenceNode.getElementsByTagName('webResult')[0];
            if (webResultNode) {
                this.SendWebResult = XmlHelper.getBooleanAttribute(webResultNode, 'sendWebResult');
                if (this.SendWebResult) {
                    this.WebResultUrl =XmlHelper.getStringAttribute(webResultNode, 'webResultUrl');
                    this.WebResultFields =XmlHelper.getStringAttribute(webResultNode, 'webFields');
                    //Author.log(Ext.String.format("WebUrl: {0}, Fields: {1}",this.WebResultUrl,this.WebResultFields));
                }
            }
        }
        this.initializeLesson(cfgXML);
    },
    registerInternalTimer:function (timer) {
        if (this.InternalTimer != null) {
           // Author.log(this.InternalTimer.toString());
        }
        this.InternalTimer = timer;
        this.InternalTimer.start();
       // Author.log("Internal Timer:\n" + this.InternalTimer.toString());
    },
    serialize:function () {
        var lessonNodeStatus = new Array();
        this.LessonNodes.each(function (node, index, length) {
            if (node.Type != 'LESSONROOT') {
                lessonNodeStatus.push({
                    id:node.id,
                    IsIntroShown:node.IsIntroductionListShown,
                    IsCompleted:node.IsCompleted
                });
            }
        }, this);

        return new LessonState({
            Variables:Author.VariableManager.saveBookMarkVariables(),
            NodesStatus:lessonNodeStatus
        });
    },
    deserialze:function (stateObject) {
        Author.LessonManager.log("Loaded saved lesson status:\n" + stateObject.SavedTime);
        Author.VariableManager.loadBookMarkVariables(stateObject.Variables);
        if (typeof(stateObject.NodesStatus) == 'undefined') {
            return;
        }
        if (!Ext.isArray(stateObject.NodesStatus)) {
            return;
        }
        Ext.Array.forEach(stateObject.NodesStatus, function (item, index, allItems) {
            var node = this.getLessonNodeByID(item.id);
            if (node) {
               // node.IsIntroductionListShown = item.IsIntroShown;
                node.IsCompleted = item.IsCompleted;
               // Author.log(Ext.String.format("Status loaded for lesson node {0}[{1}]", node.Name, node.Type));
            } else {
                Author.log(Ext.String.format("Lesson node {0} doesn't exists.", item.id));
            }
        }, this);
    },
    addLessonNode:function (node) {
        if (this.LessonNodes.containsKey(node.id)) {
            alert("Node already exists. \n" + node);
            return;
        }
        this.LessonNodes.add(node.id, node);
    },
    getLessonNodeByID:function (id) {
        if (this.LessonNodes.containsKey(id)) {
            return this.LessonNodes.getByKey(id);
        }
        else {
            return null;
        }
    },
    initializeLesson:function (cfgXML) {
        var startTime = new Date().getTime();


        var lessonRootNode = cfgXML.getElementsByTagName('lessonRoot')[0];
        this.LessonRoot = new LessonRootClass(lessonRootNode, {});
        this.addLessonNode(this.LessonRoot);
        var lessonNodes = cfgXML.getElementsByTagName('lessonNode');
        for (var i = 0; i < lessonNodes.length; i++) {
            var parentID = lessonNodes[i].getAttribute('parent');
            var parentNode = this.getLessonNodeByID(parentID);
            if (parentNode) {
                var aLessonNode = LessonNodeHelper.loadLessonNode(lessonNodes[i], parentNode, {});
                this.addLessonNode(aLessonNode);
            }
            else {
                alert("can't find parentNode with ID: " + parentID);
            }
        }
        var endTime = new Date().getTime();
        this.IsInitialized = true;
        if(this.IsTimeoutEnabled && this.Timeout>0){
            var that = this;
            this.TimeoutTimer = setTimeout(function(){
                if (that.hasListener('lessonTimeout')) {
                    that.fireEvent('lessonTimeout', that);
                }
            },this.Timeout * 1000);
        }

        if (this.hasListener('lessonInitialized')) {
            this.fireEvent('lessonInitialized', this, (endTime - startTime));
        }
    },
    toString:function () {
        return Ext.String.format("Lesson: {0}", this.Name);
    },
    getLessonScore:function (visitedElementsOnly) {
        if(this.UseCompletionAsScore)
        {
            return Author.VariableManager.getSystemVariableValue(AuthorSystemVariables.PERCENT_COMPLETE,0)
        }
        else
        {
            return this.LessonRoot.ChildNode.getOptionScore(visitedElementsOnly);
        }
    },
    getLessonTotal:function (visitedElementsOnly) {
        return this.LessonRoot.ChildNode.getOptionTotal(visitedElementsOnly);
    }
});
