/* 
 * Copyright (C) 2008 Church of Scientology International.
 * All Rights Reserved.  Confidential and proprietary.
 */

/**
 * CourseUi class.
 */
var CourseUi = function(aCourseId) {

    var myThis = this;

    this.courseId = aCourseId;
    //this.assignment = this.course.assignments[0];
    this.mainTabView = new YAHOO.widget.TabView('maintabs');
    this.mainTabView.addListener("activeTabChange", function(aEvent) {
        //alert('whoa?');
        myThis.mainTabViewActiveIndexChanged(myThis.mainTabView.getTabIndex(aEvent.newValue));
    });

    this.sendButton = new YAHOO.widget.Button("sendButton");
    this.sendButton.on("click", function(aEvent) {
        myThis.courseUiState.onSendButtonClick(aEvent);
    });
    
    this.downloadButton = new YAHOO.widget.Button("downloadButton");
    this.downloadButton.on("click", function(aEvent) {
        document.location = '/files/booklets/download/' + myThis.courseId + '-en.pdf'
    });
    
    this.completionSaveButton = new YAHOO.widget.Button("completionSaveButton");
    this.completionSaveButton.on("click", function(aEvent) {
        myThis.courseUiState.onCompletionSaveButtonClick(aEvent);
    });
    
    
//3	    var tab0 = myTabs.getTab(0); 
//4	     
//5	    function handleClick(e) {   
//6	        alert(e.target); 
//7	    } 
//8	     
//9	    tab0.addListener('click', handleClick);     
    
};

/**
 * Initialize
 */
CourseUi.prototype.init = function(aCourseId, aAssignmentNumber, aAssignmentIndex) {
    
    var myThis = this;
    
    // enable reverse AJAX, default options are fine
    dwr.engine.setActiveReverseAjax(true);

    //this.mainTabView.set('activeIndex', 0);
    
    // set an interval timer to do periodic requests to keep the session alive
    var myCallback = {
        success: function(o) {
            // noop
        },
        failure: function(o) {
            // noop
        }
    };
    
    setInterval(function() {
        YAHOO.util.Connect.asyncRequest("GET", "/course/keepalive.html?.rnd=" + Math.random(), myCallback);
    }, 15000);
    
    // retrieve all of the info about this course in one shot
    CoursePublicApi.getCourseInfo(this.courseId, function(aResult) {
        myThis.courseInfo = aResult;
        $('navCourseName').innerHTML = myThis.courseInfo.course.name;
        myThis.configScreen();
        
        if (aAssignmentIndex != null) {
            myThis.selectQuestion(aAssignmentIndex);
        }
        else if (aAssignmentNumber && (aAssignmentNumber+"").length > 0) {
            for (var i = 0; i < myThis.courseInfo.assignments.length; i++) {
                if (parseInt(myThis.courseInfo.assignments[i].number) == parseInt(aAssignmentNumber+"")) {
                    myThis.selectQuestion(i);
                    break;
                }
            }
        }
        else {
            myThis.selectQuestion(-1);
        }
    });
    
}

/**
 * Configure the screen - needs to be called after this.courseInfo exists
 */
CourseUi.prototype.configScreen = function() {
    
    var mySideNavDiv = document.getElementById('sideNavDiv');
    
    var mySideNavHtml = '';
    
    var myTableFunc = function(aNum, aGuts) {
        var myString =
            '<table cellpadding="0" cellspacing="0" border="0" width="100%"><tr><td width="16">' +
            '<img alt="Correction Needed" id="questionImgAttn' + aNum + '" src="/course/images/icon-attn.png" style="display:none">' +
            '<img alt="Completed" id="questionImgComp' + aNum + '" src="/course/images/icon-comp.png" style="display:none">' +
            '<img alt="Awaiting Review" id="questionImgSubm' + aNum + '" src="/course/images/icon-subm.png" style="display:none">' +
            '</td><td align="right">' + aGuts + '</td></tr></table>';
        return myString;
    };
    
    // instructions are "-1"
    mySideNavHtml += '<div class="questionNav" id="questionDiv-1" style="padding: 6px; padding-right: 10px;">' +
        myTableFunc(-1, '<a id="questionA-1" href="javascript:;" onclick="document.courseUi.niceSelectQuestion(-1);return false;" style="color: #FFFFFF; text-decoration: none">Instructions</a>') +
        '</div>';
    
    // loop over assignments
    for (var i = 0; i < this.courseInfo.assignments.length; i++) {
        //alert(this.courseInfo.assignments["1"]);
        var myAssignment = this.courseInfo.assignments[i];
        mySideNavHtml += '<div class="questionNav" id="questionDiv' + i + '" style="text-align: right; padding: 6px; padding-right: 10px;">' +
            myTableFunc(i, '<a id="questionA' + i + '" href="javascript:;" onclick="document.courseUi.niceSelectQuestion(' + i + ');return false;" style="color: #FFFFFF; text-decoration: none">Practical #' + myAssignment.number + '</a>') + 
            '</div>';
    }
    
    // course completion is "-2"
    mySideNavHtml += '<div class="questionNav questionNavLast" id="questionDiv-2" style="text-align: right; padding: 6px; padding-right: 10px;">' + 
        myTableFunc(-2, '<a id="questionA-2" href="javascript:;" onclick="document.courseUi.niceSelectQuestion(-2);return false;" style="color: #FFFFFF; text-decoration: none">Course Completion</a>') +
        '</div>';
    
    mySideNavDiv.innerHTML = mySideNavHtml;
    
    // fix for IE6 pngs
    fixPngs();
    
};

/**
 * Calls selectQuestion, but checks with the current CourseUiState to make
 * sure that this is acceptable - possibly prompting the current user to confirm
 * that he wants to do this.
 */
CourseUi.prototype.niceSelectQuestion = function(aIndex) {

    var myThis = this;

    // if we're already there, then don't do anything
    if (this.currentAssignmentIndex == aIndex) {
        return;
    }

    if (this.courseUiState) {
        this.courseUiState.beforeNavigateAway(function(aContinue) {
            if (aContinue) {
                myThis.selectQuestion(aIndex);
            }
        });
    }
    else {
        this.selectQuestion(aIndex);
    }
    
};

/**
 * Select a specific question.
 */
CourseUi.prototype.selectQuestion = function(aIndex) {
    
    if (aIndex < 0) {
        this.currentAssignmentIndex = aIndex;
        this.currentAssignment = null;
        this.currentLesson = null;
    }
    else {
        this.currentAssignmentIndex = aIndex;
        this.currentAssignment = this.courseInfo.assignments[aIndex];
        this.currentLesson = this.courseInfo.lessonMap[this.currentAssignment.number];
    }
    
    // do the formatting of the question buttons on the right
    
    var myDiv;
    var myA;
    
    for (var i = -2; i < this.courseInfo.assignments.length; i++) {
        var myAssignment = this.courseInfo.assignments[i];
        // make "unselected"
        myDiv = document.getElementById("questionDiv" + i);
        myDiv.style.backgroundColor = "#FFFFFF";
        myA = document.getElementById("questionA" + i);
        myA.style.color = "#000033";
        // update the icon state
        $('questionImgAttn' + i).style.display = 'none';
        $('questionImgComp' + i).style.display = 'none';
        $('questionImgSubm' + i).style.display = 'none';
        // for actual questions...
        if (myAssignment) {
            var myLesson = this.courseInfo.lessonMap[myAssignment.number];
            if (myLesson.lessonState.value == "TO_BE_REVIEWED") {
                $('questionImgSubm' + i).style.display = '';
            }
            else if (myLesson.lessonState.value == "ACCEPTED") {
                $('questionImgComp' + i).style.display = '';
            }
            else if (myLesson.lessonState.value == "REJECTED") {
                $('questionImgAttn' + i).style.display = '';
            }
            else {
                // no op
            }
        }
        //this.courseInfo.lessonMap[this.currentAssignment.number]
    }
    // now mark "selected" the appropriate one
    myDiv = document.getElementById("questionDiv" + aIndex);
    myDiv.style.backgroundColor = '#7f7f7f';
    myA = document.getElementById("questionA" + aIndex);
    myA.style.color = "#FFFFFF";
    pageTracker._trackPageview('/course/main/selectlesson/');
    // set the state to whatever is appropriate based on the current assignment
    this.autoSetState();
    
};

/**
 * Called when a tab is selected
 */
CourseUi.prototype.mainTabViewActiveIndexChanged = function(aIndex) {
    //alert('hi' + aIndex);
    if (aIndex == 0) {
        if ($('bookletContentIframe')) {
            $('bookletContentIframe').style.display = '';
            $('bookletContentIframe').src = 
                $('bookletContentIframe').src + "?"
        }
    }
    else {
        if ($('bookletContentIframe')) {
            $('bookletContentIframe').style.display = 'none';
        }
    }
    pageTracker._trackPageview('/course/main/selecttab');
}

/**
 * Set the state according to the currently selected assignment
 */
CourseUi.prototype.autoSetState = function() {
    
    // instructions page
    if (this.currentAssignmentIndex == -1) {
        this.courseUiState = new CourseUiInstructionsState(this);
    }
    
    // course completion page
    else if (this.currentAssignmentIndex == -2) {
        this.courseUiState = new CourseUiCompletionState(this);
    }
    
    // state is based on current lesson
    else {
    
        var myStateName = this.currentLesson.lessonState.value;

        if (myStateName == 'NONE') {
            this.courseUiState = new CourseUiNewState(this);
        }
        else if (myStateName == 'TO_BE_REVIEWED') {
            this.courseUiState = new CourseUiToBeReviewedState(this);
        }
        else if (myStateName == 'ACCEPTED') {
            this.courseUiState = new CourseUiAcceptedState(this);
        }
        else if (myStateName == 'REJECTED') {
            this.courseUiState = new CourseUiRejectedState(this);
        }
      
    }
    
    this.courseUiState.init();
};

/**
 * Pass true to prevent the user from navigating away from the current page.
 * Or false to turn this feature off and let him do so.
 */
CourseUi.prototype.setPreventMisNav = function(aPreventMisNav) {
    var myFunction = function() {
        if (tinyMCE.get('responseTextArea') && tinyMCE.get('responseTextArea').isDirty()) {
            var myRet = "Leaving this page now will lose any unsaved changes.";
            return myRet;
        }
        return null;
    };
    window.onbeforeunload = (aPreventMisNav) ? myFunction : null;
};

/**
 * Invoked by reverse AJAX calls to inform us of changes in state of lesson status
 */
CourseUi.prototype.onCourseEvent = function(aUserId, aCourseId, aAssignmentNumber, aLessonState) {
    
    if (aUserId == this.courseInfo.student.uid && aCourseId == this.courseInfo.course.id) {
        
        var myTimeString = getCurrentTimeFormatted();
        
        $('eventMessageDetailSpan').innerHTML = '(' + myTimeString + ') Practical #' + aAssignmentNumber + ' has been graded.';
        $('eventMessageDiv').style.visibility = 'visible';
        $('eventMessageRefreshA').href = 'index.html?courseId=' + this.courseInfo.course.id + '&assignmentNumber=' + aAssignmentNumber + '&.rnd=' + Math.random();
    }
};

////////////////////////////////////////////////////////////////////////////////
// UI State Classes
////////////////////////////////////////////////////////////////////////////////

/**
 * CourseUiState acts as the base class
 */
var CourseUiState = Base.extend({
    
    /**
     * Constructor
     */
    constructor: function(aCourseUi) {
        this.courseUi = aCourseUi;
    },
    
    /**
     * Called to initialize this state
     */
    init: function() {
    
        // default behavior is to just show the question data, update
        // the status and hide all response-related boxes and let the
        // subclass decide which of these to show

        $('practicalInstructions').style.display = 'none';
        $('practicalCompletion').style.display = 'none';
        $('practicalContents').style.display = '';

        // now populate the actual guts of the practical tab
        var myQuestion = this.courseUi.currentAssignment;
        document.getElementById('questionText').innerHTML = myQuestion.text;

        document.getElementById('enterResponseDiv').style.display = 'none';
        document.getElementById('displayResponseDiv').style.display = 'none';

        // set the text area
        var myText = this.courseUi.currentLesson.lessonText;
        myText = optionalAppendToString(myText, '<p>');
        if (tinyMCE.get('responseTextArea')) {
            tinyMCE.get('responseTextArea').setContent(myText);
            tinyMCE.get('responseTextArea').isNotDirty = 1;
        }

        // set the content div
        document.getElementById("displayResponseContentDiv").innerHTML = this.courseUi.currentLesson.lessonText;

        // set the status text
        //document.getElementById("statusText").innerHTML = 
        //      document.courseStrings.getString(this.courseUi.currentLesson.lessonState.value);

        $('editLink').style.display = '';

        // flip tabview to the practical tab
        this.courseUi.mainTabView.set('activeIndex', 1);
    
        this.courseUi.setPreventMisNav(false);
    },

    /**
     * Called when the user clicks "edit" to display the editor box
     */
    onEditButtonClick: function(aEvent) {
        
        // switch to edit view
        document.getElementById('enterResponseDiv').style.display = '';
        document.getElementById('displayResponseDiv').style.display = 'none';
        
    },

    /**
     * Called when the user clicks "send" to send the message to be graded
     */
    onSendButtonClick: function(aEvent) {

        var myThis = this;
        
        CoursePublicApi.updateLessonAndGetCourseInfo(
            this.courseUi.courseInfo.course.id,
            this.courseUi.currentAssignment.number,
            tinyMCE.get('responseTextArea').getContent(),
            false,
            function(aResult) {
                myThis.onLessonUpdateComplete(aResult);
            }
        )
        
    },
    
    /**
     * Doesn't do anything by default
     */
    onCompletionSaveButtonClick: function(aEvent) {
        // no-op
    },

    /**
     * Called by onSendButtonClick when the lesson update call completes
     */
    onLessonUpdateComplete: function(aCourseInfo) {
        
        // assign new course info
        this.courseUi.courseInfo = aCourseInfo;
        
        // select question again to update state
        this.courseUi.selectQuestion(this.courseUi.currentAssignmentIndex);
        
    },

    /**
     * Called when the user tries to go to a different question or otherwise
     * loose the state of the current question.  No value is returned, the
     * callback is called when it is known that navigation can proceed.
     * @param aCallback - called with a single parameter - either true or false,
     *                    that indicates if the navigation should proceed.
     */
    beforeNavigateAway: function(aCallback) {
        if (tinyMCE.get('responseTextArea') && tinyMCE.get('responseTextArea').isDirty()) {
            aCallback(confirm("Are you sure you want to navigate away from this question?  You will lose any unsaved changes."));
        }
        else {
            aCallback(true);
        }
    }
    
});

/**
 * The Instructions state - we are currently displaying instructions.
 */
var CourseUiInstructionsState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
   
    init: function() {
        
        $('practicalInstructions').style.display = '';
        $('practicalCompletion').style.display = 'none';
        $('practicalContents').style.display = 'none';
        
        // flip tabview to the practical tab
        this.courseUi.mainTabView.set('activeIndex', 1);
    }
    
});

/**
 * The Completion state - we are currently displaying the completion page.
 */
var CourseUiCompletionState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
   
    init: function() {
        
        $('practicalInstructions').style.display = 'none';
        $('practicalCompletion').style.display = '';
        $('practicalContents').style.display = 'none';

        /*
        IN_PROGRESS("IN_PROGRESS"),
         *COMPLETED_NEED_ADDRESS_CONFIRM
        COMPLETED_AWAITING_CERT("COMPLETED_AWAITING_CERT"),
        COMPLETED_SENT_CERT("COMPLETED_SENT_CERT");
        */
        
        var myEnrollmentState = this.courseUi.courseInfo.enrollment.enrollmentState.value;
        var myStudent = this.courseUi.courseInfo.student;
        
        $('practicalCompletionNotDoneDiv').style.display = 'none';
        $('practicalCompletionAddressConfirmDiv').style.display = 'none';
        $('practicalCompletionInCertQueueDiv').style.display = 'none';
        $('practicalCompletionSentDiv').style.display = 'none';
        
        // need to confirm address, so we config the form fo rhtat
        if (myEnrollmentState == 'COMPLETED_NEED_ADDRESS_CONFIRM') {
            // no previous value for these "completion" fields, so we populate
            // from main entries in the student record
            if (myStudent.completionFullName == null) {
                $('completionFullName').value = myStudent.firstName + ' ' + myStudent.lastName;
                $('completionAddress1').value = myStudent.address1;
                $('completionAddress2').value = myStudent.address2;
                $('completionCity').value = myStudent.city;
                $('completionStateProvince').value = myStudent.stateProvince;
                $('completionPostalCode').value = myStudent.postalCode;
                $('completionCountryCode').value = myStudent.countryCode;
                $('completionHomePhone').value = myStudent.homePhone;
                $('completionWorkPhone').value = myStudent.workPhone;
                $('completionEmailAddress').value = myStudent.emailAddress;
            }
            else {
                $('completionFullName').value = myStudent.completionFullName;
                $('completionAddress1').value = myStudent.completionAddress1;
                $('completionAddress2').value = myStudent.completionAddress2;
                $('completionCity').value = myStudent.completionCity;
                $('completionStateProvince').value = myStudent.completionStateProvince;
                $('completionPostalCode').value = myStudent.completionPostalCode;
                $('completionCountryCode').value = myStudent.completionCountryCode;
                $('completionHomePhone').value = myStudent.completionHomePhone;
                $('completionWorkPhone').value = myStudent.completionWorkPhone;
                $('completionEmailAddress').value = myStudent.completionEmailAddress;
            }
            
            $('practicalCompletionAddressConfirmDiv').style.display = '';
        }
        else if (myEnrollmentState == 'COMPLETED_AWAITING_CERT') {
            $('practicalCompletionInCertQueueDiv').style.display = '';
        }
        else if (myEnrollmentState == 'COMPLETED_SENT_CERT') {
            $('practicalCompletionSentDiv').style.display = '';
        }
        else /* if IN_PROGRESS */ {
            // show the "course still in progress message"
            $('practicalCompletionNotDoneDiv').style.display = '';
        }
        
        // flip tabview to the practical tab
        this.courseUi.mainTabView.set('activeIndex', 1);
    },
    
    /**
     * Handle the user's saving his contact data so he can get his cert
     */
    onCompletionSaveButtonClick: function(aEvent) {
        
        var myMap = {
            completionFullName: $('completionFullName').value+'',
            completionAddress1: $('completionAddress1').value+'',
            completionAddress2: $('completionAddress2').value+'',
            completionCity: $('completionCity').value+'',
            completionStateProvince: $('completionStateProvince').value+'',
            completionPostalCode: $('completionPostalCode').value+'',
            completionCountryCode: $('completionCountryCode').value+'',
            completionHomePhone: $('completionHomePhone').value+'',
            completionWorkPhone: $('completionWorkPhone').value+'',
            completionEmailAddress: $('completionEmailAddress').value+''
        };
        
        var myCourse = this.courseUi.courseInfo.course;
        
        // update the info and refresh the page
        CoursePublicApi.updateStudentCompletionInfo(myCourse.id+'', myMap, function(aResult) {
            document.location = 'index.html?courseId=' + myCourse.id + '&assignmentIndex=-2&.rnd=' + Math.random();
        });
        
    }
    
});

/**
 * The New state - for assignments which haven't been answered at all
 */
var CourseUiNewState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
   
    init: function() {
        this.base();
        document.getElementById('enterResponseDiv').style.display = '';
        this.courseUi.setPreventMisNav(true);
        
        $('statusSymbolToBeReviewed').style.display = 'none';
        $('statusSymbolRejected').style.display = 'none';
        $('statusSymbolAccepted').style.display = 'none';
        
    }
    
//    beforeNavigateAway: function(aCallback) {
//        aCallback(confirm('Are you sure?'));
//    }
    
});

/**
 * The "to be reviewed" state.
 */
var CourseUiToBeReviewedState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
    
    init: function() {
        this.base();
        document.getElementById('displayResponseDiv').style.display = '';
        
        $('statusSymbolToBeReviewed').style.display = '';
        $('statusSymbolRejected').style.display = 'none';
        $('statusSymbolAccepted').style.display = 'none';
        
    },

    /**
     * Only difference in this override is to pass true as the edit param, so
     * it doesn't append a new header if the user is editing what he just typed.
     */
    onSendButtonClick: function(aEvent) {

        var myThis = this;
        
        CoursePublicApi.updateLessonAndGetCourseInfo(
            this.courseUi.courseInfo.course.id,
            this.courseUi.currentAssignment.number,
            tinyMCE.get('responseTextArea').getContent(),
            true,
            function(aResult) {
                myThis.onLessonUpdateComplete(aResult);
            }
        )
        
    }
    
});

/**
 * The "accepted" state.
 */
var CourseUiAcceptedState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
    
    init: function() {
        this.base();
        document.getElementById('displayResponseDiv').style.display = '';
        
        $('editLink').style.display = 'none';
        
        $('statusSymbolToBeReviewed').style.display = 'none';
        $('statusSymbolRejected').style.display = 'none';
        $('statusSymbolAccepted').style.display = '';
    }
    
});

/**
 * The "rejected" state.
 */
var CourseUiRejectedState = CourseUiState.extend({
    
    constructor: function(aCourseUi) {
        this.base(aCourseUi);
    },
    
    init: function() {
        this.base();
        document.getElementById('displayResponseDiv').style.display = '';
        
        this.courseUi.setPreventMisNav(true);
        
        $('statusSymbolToBeReviewed').style.display = 'none';
        $('statusSymbolRejected').style.display = '';
        $('statusSymbolAccepted').style.display = 'none';
    }
    
});
