/* ======================================================================
   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.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;
import java.util.Vector;

import java.sql.Timestamp;

import org.bodington.assessment.QuestionnaireFacility.QuestionnaireRenderer;
import org.bodington.util.DateFormatter;

/**
 * Abstract class for rendering questionnaires. This class captures some of the
 * commonality in concrete renderer subclasses.
 * @author Alexis O'Connor
 */
abstract class AbstractQuestionnaireRenderer implements QuestionnaireRenderer
    {
    /**
     * Get a list of messages about the current questionnaire and result. The
     * list returned by this method is guaranteed to be <code>mutable</code> in
     * order to permit subclasses to override this method and add messages to 
     * it (if required).
     * @param questionnaire the questionnaire itself.
     * @param result the questionnaire result.
     * @return a list of messages about the current questionnaire and result.
     */
    protected List getMessages( Questionnaire questionnaire,
        QuestionnaireResult result )
        {
        Vector messages = new Vector();

        // Deadline:
        String deadlineMessage = null;
        Timestamp deadline = questionnaire.getDeadline();
        boolean hasPassed = deadline != null && new Date().after( deadline );
        if ( deadline != null )
            {
            String wasis = hasPassed ? "was" : "is";
            deadlineMessage = "The deadline for submissions " + wasis + " "
                + DateFormatter.formatDate( deadline, DateFormatter.MEDIUM ) + ".";
            }
        
        if (hasPassed)
            messages.add( deadlineMessage );
        
        if ( questionnaire.isAnonymous()
            || questionnaire.isPartiallyAnonymous() )
            {
            messages.add( "Your answers will be anonymous." );
            }
        else
            {
            messages.add( "Your answers will be associated with your name." );
            }
        
        if ( questionnaire.isPartiallyAnonymous() )
            messages.add( "Non-respondents will be visible to the "
                + "questionnaire creator." );

        
        if ( questionnaire.isMultipleResults() )
            {
            messages.add( "You can record more than one set of answers.");
            }
        else
            {
            messages.add( "You will only be able to record one set of answers.");
            }
        
        if ( questionnaire.isMultipleAttempts() )
            {
            messages.add( "You will have the opportunity to subsequently edit "
                + "your answers." );
            }
        else
            {
            messages.add( "Your answers can not subsequently be modified." );
            }

        // Message submission status - pertinent to single result types:
        if ( !questionnaire.isMultipleResults() )
            {
            if ( result == null )
                {
                messages.add( "You have not yet submitted a response." );
                }
            else
                {
                messages.add( "You have already submitted a response." );
                }
            }
        
        // The deadline is ...
        if ( deadline != null && !hasPassed )
            messages.add( deadlineMessage );

        return messages;
        }
    
    protected void cancelButton(PrintWriter out)
        {
        out.println("<input type=\"submit\" name=\"CANCEL\" "
            + "value=\"Cancel\" style=\"margin-left: 15px\"/>");
        }
    
    protected void submitButton(PrintWriter out)
        {
        out.println("<input type=\"submit\" name=\"RECORD\" "
            + "value=\"Submit\" />");
        }

    /**
     * Get the selected responses to the multiple choice element of a question.
     * The form of the returned collection is
     * <code>Collection &lt;Integer&gt;</code> where each item represents the
     * index of a chosen response.
     * @param question the question being answered.
     * @param response the response to the question
     * @return the selected responses to the multiple choice element of a
     *         question.
     */
    protected Collection selection( QuestionnaireQuestion question, 
        QuestionnaireResponse response )
        {
        TreeSet selected = new TreeSet(); // TreeSet keeps numerical ordering.
        if ( response == null )
            return selected;
        
        if ( question.isMultipleResponse() )
            {
            byte[] responses = response.getSelection();
            for (int i = 0; i < responses.length; i++)
                selected.add( new Integer( responses[i] ));
            }
        else
            {
            int item = response.getItem();
            if (item != QuestionnaireResponse.NO_SINGLE_RESPONSE )
                selected.add( new Integer( response.getItem() ) );
            }
        
        return selected;
        }
    }
