/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

====================================================================== */

package org.bodington.assessment;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.bodington.server.BuildingContext;
import org.bodington.server.BuildingServerException;
import org.bodington.server.events.Event;
import org.bodington.server.events.OpinionEvent;
import org.bodington.server.realm.User;
import org.bodington.servlet.Request;

/**
 * Class for rendering questionnaires in the <em>run</em> state. This class
 * is used to render the questions themselves, the functionality to enable the
 * recording of responses to those questions and, where appropriate, the
 * current user's existing responses.
 * @author Alexis O'Connor
 */
class RunQuestionnaireRenderer extends AbstractQuestionnaireRenderer
    {
    public void paperToHTML( Request request, PrintWriter out,
        QuestionnaireSession session ) throws IOException,
        BuildingServerException
        {
        List questions_in_order;
        Questionnaire questionnaire = null;
        QuestionnaireQuestion question;
        QuestionnaireResult result = null;
        QuestionnaireResponse response = null;
        Map responses = null;

        questionnaire = session.getQuestionnaire();
        questions_in_order = session.getQuestionnaireQuestionsInOrder();

        result = session.getQuestionnaireResult();
        // NOTE: we may null the result so that it is not rendered.
        result = questionnaire.isHideAnswersOnSubmit() ? null : result;
        responses = result != null ? result.getQuestionnaireResponses() : null;
        
        // What's this questionnaire all about?
        out.println( questionnaire.getIntroduction() );

        /*
         * Conditional messages depending on certain states:
         */ 
        List messages = getMessages( questionnaire, result );
        if ( messages.size() > 0 )
            {
            out.println("<p><em>NOTE: you should read the following points "
                + "about this questionnaire.</em>");
            out.print("<ul>");
            Iterator iter = messages.iterator();
            while (iter.hasNext())
                out.println( "<li>" + iter.next() + "</li>");
            out.print("</ul>");
            }

        out.println( "<FORM METHOD=POST target=buildmain " +
                "ACTION=bs_template_qrecord.html>" );
        for ( int i = 0; i < questions_in_order.size(); i++ )
            {
            question = (QuestionnaireQuestion)questions_in_order.get( i );
            response = (responses != null) 
                ? (QuestionnaireResponse)responses.get( 
                    question.getQuestionnaireQuestionId() ) : null;

            String identifier = "Q" + question.getQuestionnaireQuestionId();
            out.println( "<HR><TABLE id=" + identifier
                + "><TR><TD COLSPAN=3><H4>Question " + (i + 1)
                + "</H4></TD></TR>" );

            questionToHTML( question, response, out );

            out.println( "</TABLE>" );
            }

        if ( questions_in_order.size() == 0 )
            {
            out.println( "<P>There are currently no questions in this "
                + "questionnaire.</P>" );
            }

        out.println("<p>");
        
        if ( questions_in_order.size() > 0 )
            {
            // `Record' Button:
            out.println( "<div style=\"float: left; margin-left: 80px\">" );
            submitButton( out );
            out.println( "</div>" );
            User user = (User)BuildingContext.getContext().getUser();
            Event event = new OpinionEvent( OpinionEvent.EVENT_START, request
                .getResource().getResourceId(), user.getUserId(), null );
            event.save();
            }
        // Close the (main) form:
        out.println( "</form>" );

        
        // `Cancel' Button:
        out.println("<div>" );
        out.println( "<FORM METHOD=POST target=_top "
            + "ACTION=bs_template_qrecord.html>" );
        cancelButton( out );
        out.println( "</form>" );
        out.println("</div>");
        
        // Close 'Buttons' paragraph:
        out.println( "</p>" );
        }

    public void questionToHTML( QuestionnaireQuestion question,
        QuestionnaireResponse response, PrintWriter out ) throws IOException,
        BuildingServerException
        {
        out.println( "<TR><TD COLSPAN=3>" );
        out.println( "<INPUT TYPE=HIDDEN VALUE=TRUE NAME=Q"
            + question.getQuestionnaireQuestionId() + ">" );
        out.println( question.getIntroduction() );
        out.println( "</TD></TR>" );

        int[] indices = question.getValidStatementIndices();
        String controlType = question.isMultipleResponse() ? "CHECKBOX" : "RADIO";
        Collection selection = selection( question, response );
        for ( int i = 0; i < indices.length; i++ )
            {
            char letter = (char)('A' + i);
            out.println( "<TR><TD VALIGN=TOP WIDTH=20><B>" );
            out.println( letter );
            out.println( "</B></TD><TD VALIGN=TOP WIDTH=20>" );
            out.print( "<INPUT TYPE=" + controlType + " " );
            out.print( "NAME=QR" );
            out.print( question.getQuestionnaireQuestionId() );
            out.print( " VALUE=" + letter );
            if ( selection.contains( new Integer(i) ) )
                out.print( " CHECKED" );
            out.println( ">" );
            out.println( "</TD><TD VALIGN=TOP WIDTH=1000>" );
            out.println( question.getStatement( indices[i] ) );
            out.println( "</TD></TR>" );
            }

        // This enables a user to deselect a single response MCQ:
        if ( !question.isMultipleResponse() && indices.length > 0 )
            {
            out.println( "<TR><TD VALIGN=TOP WIDTH=20></TD><TD VALIGN=TOP "
                + "WIDTH=20>" );
            out.print( "<INPUT TYPE=RADIO " );
            out.println( "NAME=QR" + question.getQuestionnaireQuestionId()
                + " VALUE=X>" );
            out.println( "</TD><TD VALIGN=TOP WIDTH=1000>Cancel selection.</TD>"
                    + "</TR>" );
            }

        if ( question.isCanComment() )
            {
            out.print( "<TR>" );
            out.print( "<TD COLSPAN=3><SPAN CLASS=bs-textarea><TEXTAREA ROWS=6 "
                    + "COLS=40 NAME=QC" );
            out.print( question.getQuestionnaireQuestionId() );
            out.print( ">" );
            if ( response != null && response.getComment() != null )
                out.print( response.getComment() );
            out.println( "</TEXTAREA></SPAN></TD></TR>" );
            }
        }
    }
