/* ======================================================================
   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.servlet.facilities;

import org.apache.log4j.Logger;

import java.rmi.RemoteException;

import org.bodington.servlet.*;

import java.util.*;
import java.sql.*;
import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;

import java.math.BigDecimal;

import org.bodington.database.PrimaryKey;
import org.bodington.server.*;
import org.bodington.server.resources.Resource;
import org.bodington.server.BuildingContext;
import org.bodington.server.events.*;
import org.bodington.server.realm.User;
import org.bodington.server.realm.Group;
import org.bodington.server.realm.Member;
import org.bodington.server.realm.Acl;
import org.bodington.server.realm.AclEntry;
import org.bodington.server.realm.Permission;
import org.bodington.assessment.*;
import org.bodington.i18n.Localiser;

public class PeerMarkerFacility extends
        org.bodington.servlet.facilities.Facility {
    private static Logger log = Logger.getLogger(PeerMarkerFacility.class);

    private String leftpanel = "../bs_template_peermmoderatelist.html";

    private String rightpanel = "/bs_template_peermmoderatepaper.html";

    private String leftpanel2 = "../bs_template_peermmoderate2list.html";

    private String rightpanel2 = "/bs_template_peermmoderate2paper.html";

    Vector fileResults;

    private Localiser loc = new Localiser(
            "res.templates.style_default.peermarker.in_code",
            ((User) BuildingContext.getContext().getUser()).getLanguage());
    
    public String defaultIcon() {
        return "paper.gif";
    }

    public String defaultSmallIcon() {
        return "paper-small.gif";
    }

    public boolean canCopy(Resource resource) {
        return true;
    }

    public Resource newResource() {
        return new PeerMarkerPaper();
    }

    public List initResource(HttpServletRequest breq, Resource new_resource) {
        if (!(new_resource instanceof PeerMarkerPaper))
            throw new IllegalArgumentException(loc.getString("an.incorrect.type.of.resource"));

        PeerMarkerPaper pmp;
        pmp = (PeerMarkerPaper) new_resource;

        String param;

        param = breq.getParameter("once_only");
        if (param != null)
            if (param.equalsIgnoreCase("yes"))
                pmp.setOnceOnly(1);
            else
                pmp.setOnceOnly(0);
        else
            pmp.setOnceOnly(0);

        param = breq.getParameter("self_allowed");
        if (param != null)
            if (param.equalsIgnoreCase("yes"))
                pmp.setSelfAllowed(1);
            else
                pmp.setSelfAllowed(0);
        else
            pmp.setSelfAllowed(0);

        return super.initResource(breq, new_resource);
    }

    public boolean initResource(Resource original_resource,
            Resource new_resource) throws BuildingServerException {
        if (!(new_resource instanceof PeerMarkerPaper))
            throw new BuildingServerException(loc
                    .getString("wrong.type.of.resource"));

        PeerMarkerPaper original = (PeerMarkerPaper) original_resource;
        PeerMarkerPaper new_paper = (PeerMarkerPaper) new_resource;

        new_paper.setOnceOnly(original.getOnceOnly());
        new_paper.setSelfAllowed(original.getSelfAllowed());

        return true;
    }

    /**
     * Copy the content of one resource to another.
     * <p>
     * <h4>Content copied</h4>
     * <ul>
     * <li>authored questions.
     * </ul>
     * <h4>Content <em>not</em> copied</h4>
     * <ul>
     * <li>user answers.
     * </ul>
     * </p>
     * 
     * @param original_resource
     *            the resource whose contents are to be copied.
     * @param new_resource
     *            the resource to copy content to.
     * @param breq
     *            the building request object.
     * @throws BuildingServerException
     *             if there is any problem copying the resource content.
     */
    public void copyContent(Resource original_resource, Resource new_resource,
            Request breq) throws BuildingServerException {
        // authored : questions
        // userdata : answers? /** @todo */

        BuildingSession session = BuildingSessionManagerImpl
                .getSession(original_resource);
        if (!(session instanceof PeerMarkerSession))
            throw new BuildingServerException(loc
                    .getString("unable.to.access.session"));

        try {
            if (breq.getParameter("authored") != null) {
                copyAuthoredContent(original_resource, new_resource);
                // if ( breq.getParameter( "userdata" ) != null )
                // copyUserContent( original_resource, new_resource );
            }
        } catch (Exception ex) {
            throw new BuildingServerException(ex.getMessage());
        }
    }

    /**
     * Copy the authored content of an existing Resource to another Resource.
     * 
     * @param original_resource
     *            The resource with content to copy.
     * @param new_resource
     *            The resource to copy content to.
     * @exception BuildingServerException
     *                Thrown if there is any problem copying the resource
     *                content.
     * @exception RemoteException
     *                Thrown if there is any problem copying the resource
     *                content.
     */
    private void copyAuthoredContent(Resource original_resource,
            Resource new_resource) throws BuildingServerException,
            RemoteException {
        PeerMarkerSession session;
        Vector questions;
        PeerMarkerQuestion orig_question, new_question;

        session = (PeerMarkerSession) BuildingSessionManagerImpl
                .getSession(original_resource);
        questions = session.getPeerMarkerQuestionsInOrder();

        for (int i = 0; i < questions.size(); i++) {
            orig_question = (PeerMarkerQuestion) questions.elementAt(i);
            new_question = new PeerMarkerQuestion();
            new_question.setResourceId(new_resource.getResourceId());
            new_question.setQuestion(orig_question.getQuestion());
            new_question.setOrdinal(orig_question.getOrdinal());
            new_question.setAvailable(orig_question.getAvailable());
            new_question.save();
        }
    }

    public List postCreate(Request breq, Resource newResource)
            throws Exception {
        
        List errors = super.postCreate(breq, newResource);
        Enumeration enumeration;
        Group entrygroup;
        AclEntry entry;

        Acl acl = newResource.getAcl();
        for (enumeration = acl.entries(); enumeration.hasMoreElements();) {
            entry = (AclEntry) enumeration.nextElement();
            entrygroup = (Group) entry.getPrincipal();
            if (!entrygroup.getName().endsWith("owners"))
                continue;

            entry.removePermission(Permission.MARK);
            entry.removePermission(Permission.POST);
            entry.save();
            break;
        }

        return errors;
    }

    /**
     * Intercept requests for virtual (generated-on-demand) files specific to
     * media documents and ensure that they are generated. If a specific
     * filename is not found, this defers to its superclass.
     * 
     * @param req
     *            The request for the file.
     * @param res
     *            The servlet response through which to send the generated file
     *            to the client browser.
     */
    public void sendVirtualFile(Request req, HttpServletResponse res)
            throws ServletException, IOException {

        if (req.getPageName().equals("marks.csv")) {
            if (!BuildingContext.getContext().checkPermission("manage")) {
                res.setContentType("text/plain");
                PrintWriter writer = new PrintWriter(res.getWriter());

                writer
                        .println("You do not have permission to access this file.");
                writer.println(req.getPageName());
                writer.close();
                return;
            }
            try {
                PeerMarkerSession pm_session = (PeerMarkerSession) BuildingSessionManagerImpl
                        .getSession(req.getResource());
                exportCSVFile(req, res, pm_session);
                return;
            } catch (BuildingServerException bse) {
                res.setContentType("text/plain");
                PrintWriter writer = new PrintWriter(res.getWriter());

                writer.println("ERROR");
                writer.print("Problem generating file requested: ");
                writer.println(req.getPageName());
                writer.close();
            }
        }

        super.sendVirtualFile(req, res);
    }

    // export CVS file

    public void exportCSVFile(Request req, HttpServletResponse res,
            PeerMarkerSession pm_session) throws RemoteException,
            BuildingServerException {
        int i, j, k;
        double average;
        PeerMarkerQuestion question = null;
        PrimaryKey markerID, markeeID, questionID;

        Vector qlist = pm_session.getPeerMarkerQuestionsInOrder();
        Vector markers = pm_session.everyoneWhoCanInSiblings(Permission.MARK,
                true);
        Vector markees = pm_session.everyoneWhoCanInSiblings(Permission.POST,
                true);

        Vector siblings = pm_session.getPeerMarkerSiblings();

        String append = " and resource_id in (";
        // get the sibling resource ids
        for (i = 0; i < siblings.size(); i++) {
            if (i > 0)
                append += ",";
            append += ((PeerMarkerPaper) siblings.elementAt(i)).getPrimaryKey();
        }
        append += ")";

        if ((markees.size() == 0) || (markers.size() == 0))
            throw new BuildingServerException(loc
                    .getString("no.marks.available"));

        try {
            String mime_type = req.getServletContext()
                    .getMimeType("marks.csv");
            if (mime_type == null)
                mime_type = "text/csv";

            res.setContentType(mime_type);
            res.setHeader("Content-Disposition",
                    "inline; filename=\"marks.csv\"");
            res.setHeader("Cache-Control", "no-cache");

            PrintWriter csvout = new PrintWriter(new OutputStreamWriter(res
                    .getOutputStream()));

            for (i = 0; i < qlist.size(); i++) {

                csvout.println(loc.getString("item") + (i + 1));
                csvout.println(loc.getString("name") + ","
                        + loc.getString("average") + ","
                        + loc.getString("available") + ","
                        + loc.getString("individual.marks"));

                for (j = 0; j < markees.size(); j++) {
                    User markee = (User) markees.elementAt(j);
                    markeeID = markee.getUserId();
                    csvout.print(markee.getName());
                    // get the marks
                    int aggregate = 0;
                    int no_of_markers = 0;
                    Vector markstore = new Vector();
                    for (k = 0; k < markers.size(); k++) {
                        User marker = (User) markers.elementAt(k);
                        markerID = marker.getUserId();

                        // which question did this user mark?
                        // find which sibling resource was used
                        // then get its questions and select the appropriate one

                        // assume that each marker and markee only meet once so
                        // we should be able to
                        // start by looking for results created by the marker in
                        // the sibling resources
                        Enumeration enumres = PeerMarkerResult
                                .findPeerMarkerResults("user_id =" + markerID
                                        + append);
                        if (enumres == null)
                            continue;
                        // find the first result that involves both marker and
                        // markee
                        PeerMarkerResponse pmr = null;
                        PeerMarkerResult pmres = null;
                        while (enumres.hasMoreElements()) {
                            pmres = (PeerMarkerResult) enumres.nextElement();
                            Enumeration pmr_enum = PeerMarkerResponse
                                    .findPeerMarkerResponses("peer_marker_userid="
                                            + markerID
                                            + " and peer_markee_userid="
                                            + markeeID
                                            + " and peer_mark_result_id="
                                            + pmres.getPrimaryKey());
                            if (pmr_enum.hasMoreElements() == false)
                                continue;
                            // found a response - it may not be for the right
                            // question
                            // but at least we know that we have a result from a
                            // sibling resource
                            // where the marker marked the markee
                            pmr = (PeerMarkerResponse) pmr_enum.nextElement();
                            pmres = PeerMarkerResult.findPeerMarkerResult(pmr
                                    .getPeerMarkerResultId());
                        }
                        if (pmres == null)
                            continue;
                        Resource sib_resource = Resource.findResource(pmres
                                .getResourceId());
                        PeerMarkerSession sib_session = (PeerMarkerSession) BuildingSessionManagerImpl
                                .getSession(sib_resource);
                        // now we can get the correct question
                        Vector qlist1 = sib_session
                                .getPeerMarkerQuestionsInOrder();
                        question = (PeerMarkerQuestion) qlist1.elementAt(i);
                        questionID = question.getPrimaryKey();
                        // and finally locate the correct response
                        pmr = pm_session.getPeerMarkerResponse(markerID,
                                markeeID, questionID);
                        if (pmr == null)
                            continue;
                        Integer mark = pmr.getModeratedMark();
                        if (pmr.getMarkAllowed() == 1) {
                            aggregate += mark.intValue();
                            no_of_markers++;
                            markstore.add(mark);
                        }

                    }
                    if (no_of_markers > 0) {
                        average = (double) aggregate / (double) no_of_markers;
                        // round to 2 decimal places
                        BigDecimal bd = new BigDecimal(average);
                        bd = bd.setScale(2, BigDecimal.ROUND_UP);
                        average = bd.doubleValue();
                        csvout.print("," + average);
                    } else
                        csvout.print(",");

                    csvout.print("," + question.getAvailable());

                    for (k = 0; k < markstore.size(); k++)
                        csvout
                                .print(","
                                        + ((Integer) markstore.elementAt(k))
                                                .intValue());
                    csvout.println();

                }
                csvout.println();
            }
            csvout.close();

        } catch (IOException ioex) {
            log.error(ioex);
            throw new BuildingServerException(loc.getString("csv.file.problem")
                    + ioex.getMessage());
        }
    }

    public void insert(Request req, PrintWriter out, String command,
            String insertname) throws ServletException, IOException {
        log.debug(Thread.currentThread().getName()
                + " PeerMarkerFacility insert()");

        try {
            BuildingSession session;
            PeerMarkerSession pm_session;

            session = BuildingSessionManagerImpl.getSession(req.getResource());
            if (!(session instanceof PeerMarkerSession)) {
                out.println("<hr/>"
                        + loc.getString("unable.to.access.tool.session")
                        + "<hr/>");
                return;
            }
            pm_session = (PeerMarkerSession) session;

            if (command.equalsIgnoreCase("peermmain1")
                    || command.equalsIgnoreCase("peermmain2")
                    || command.equalsIgnoreCase("peermsiblings")
                    || command.equalsIgnoreCase("peermfield")
                    || command.equalsIgnoreCase("peermmodify")
                    || command.equalsIgnoreCase("peermpaper")
                    || command.equalsIgnoreCase("peermpaper2")
                    || command.equalsIgnoreCase("peermrecord")
                    || command.equalsIgnoreCase("peermitemedit")
                    || command.equalsIgnoreCase("peermeditqconfirm")
                    || command.equalsIgnoreCase("peermdeleteq")
                    || command.equalsIgnoreCase("peermmoderatelist")
                    || command.equalsIgnoreCase("peermmoderate2list")
                    || command.equalsIgnoreCase("peermmoderateconfirm")
                    || command.equalsIgnoreCase("peermmoderate2confirm")
                    || command.equalsIgnoreCase("peermrunbutton")
                    || command.equalsIgnoreCase("ifcanmark")
                    || command.equalsIgnoreCase("ifentry")
                    || command.equalsIgnoreCase("noupmessage")
                    || command.equalsIgnoreCase("onceonlymessage")
                    || command.equalsIgnoreCase("export")
                    || command.equalsIgnoreCase("peermnewitem")) {

                if (out == null)
                    return;

                if (command.equalsIgnoreCase("ifcanmark"))
                    ifcanmark(req, out, pm_session);

                if (command.equalsIgnoreCase("ifentry"))
                    ifentry(req, out, pm_session);

                if (command.equalsIgnoreCase("noupmessage"))
                    noupmessage(req, out, pm_session);

                if (command.equalsIgnoreCase("peermfield"))
                    peermfield(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermmodify"))
                    peermmodify(req, out, pm_session);

                if (command.equalsIgnoreCase("peermpaper"))
                    peermpaper(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermpaper2"))
                    peermpaper2(req, out, pm_session);

                if (command.equalsIgnoreCase("peermmoderatelist"))
                    peermlist(req, out, pm_session);

                if (command.equalsIgnoreCase("peermmoderate2list"))
                    peermlist2(req, out, pm_session);

                if (command.equalsIgnoreCase("peermmoderateconfirm"))
                    peermrecord(req, out, pm_session, "moderate");

                if (command.equalsIgnoreCase("peermmoderate2confirm"))
                    peermrecord2(req, out, pm_session);

                if (command.equalsIgnoreCase("peermrecord"))
                    peermrecord(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermnewitem"))
                    peermnewitem(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermitemedit"))
                    peermitemedit(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermeditqconfirm"))
                    peermeditqconfirm(req, out, pm_session, insertname);

                if (command.equalsIgnoreCase("peermdeleteq"))
                    peermdeleteq(req, out, pm_session);

                if (command.equalsIgnoreCase("onceonlymessage"))
                    onceonlymessage(req, out, pm_session);

                if (command.equalsIgnoreCase("peermrunbutton"))
                    peermrunbutton(req, out, pm_session);

                if (command.equalsIgnoreCase("peermsiblings"))
                    peermsiblings(req, out, pm_session);

                if (command.equalsIgnoreCase("export"))
                    exportCSV(req, out, pm_session);

                if (command.equalsIgnoreCase("peermmain1"))
                    peermmain1(req, out);

                if (command.equalsIgnoreCase("peermmain2"))
                    peermmain2(req, out);

                return;
            }
        } catch (BuildingServerException bsex) {
            out.println(bsex.toString());
            return;
        }

        super.insert(req, out, command, insertname);
    }

    public boolean ifcanmark(Request req, PrintWriter out) {
        try {
            PeerMarkerSession pm_session = (PeerMarkerSession) BuildingSessionManagerImpl
                    .getSession(req.getResource());
            return ifcanmark(req, out, pm_session);
        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "ifcanup",
                    "Technical error looking for an entry in the database.", ex);
            return false;
        }
    }

    // i.e. can submit answers to questions
    private boolean ifcanmark(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws ServletException, IOException {
        try {
            if (pm_session.canSubmit()) {
                req.setSwitchedOff(false);
                return true;
            } else {
                req.setSwitchedOff(true);
                return false;
            }
        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "ifcanup",
                    "Technical error looking for an entry in the database.", ex);
            return false;
        }

    }

    private void noupmessage(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws ServletException, IOException {

        try {
            if (!pm_session.canSubmit())
                out.print(pm_session.denySubmitMessage());
        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "noupmessage",
                    "Technical error looking for an entry in the database.", ex);
            return;
        }

    }

    // allows both panels to be updated without Javascript
    private void peermmain1(Request req, PrintWriter out) {

        String param;
        if (req.getTemplateParameterCount() < 1) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        param = (String) req.getTemplateParameter(0);
        if (param == null) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        // Strip away any accumulated Bodington parameters
        String[] parameters = rightpanel.split("/");
        // down to the bare filename
        rightpanel = parameters[parameters.length - 1];

        out.println("<frameset cols=\"30%,*\" frameborder=\"0\">");
        out.print("<frame src=\"");
        out.print(leftpanel);
        out
                .println("\" name=\"doccontents\" title=\"Contents Frame\" marginwidth=\"10\" marginheight=\"10\" frameborder=\"0\" noresize=\"noresize\"/>");
        out.print("<frame src=\"");
        // put in the current parameter
        out.print("../" + param + "/" + rightpanel);
        out
                .println("\" name=\"docmain\" title=\"Main Frame\" marginwidth=\"10\" marginheight=\"10\" frameborder=\"0\" noresize=\"noresize\"/>");
        out.println("</frameset>");

        // Now shows the new left and right panels

    }

    private void peermmain2(Request req, PrintWriter out) {

        String param;
        if (req.getTemplateParameterCount() < 1) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        param = (String) req.getTemplateParameter(0);
        if (param == null) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        // Strip away any accumulated Bodington parameters
        String[] parameters = rightpanel2.split("/");
        // down to the bare filename
        rightpanel2 = parameters[parameters.length - 1];

        out.println("<frameset cols=\"30%,*\" frameborder=\"0\">");
        out.print("<frame src=\"");
        out.print(leftpanel2);
        out
                .println("\" name=\"doccontents\" title=\"Contents Frame\" marginwidth=\"10\" marginheight=\"10\" frameborder=\"0\" noresize=\"noresize\"/>");
        out.print("<frame src=\"");
        // put in the current parameter
        out.print("../" + param + "/" + rightpanel2);
        out
                .println("\" name=\"docmain\" title=\"Main Frame\" marginwidth=\"10\" marginheight=\"10\" frameborder=\"0\" noresize=\"noresize\"/>");
        out.println("</frameset>");

        // Now shows the new left and right panels

    }

    private void onceonlymessage(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws ServletException, IOException {

        try {
            if (pm_session.getPeerMarkerPaper().getOnceOnly() == 1)
                out.print("<span style=\"color:red\">"
                        + loc.getString("you.are.only.allowed.one.attempt")
                        + "</span>");
        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "onceonlymessage",
                    "Technical error looking for an entry in the database.", ex);
            return;
        }

    }

    public boolean ifentry(Request req, PrintWriter out) {
        try {
            PeerMarkerSession pm_session = (PeerMarkerSession) BuildingSessionManagerImpl
                    .getSession(req.getResource());
            return ifentry(req, out, pm_session);
        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "ifcanup",
                    "Technical error looking for an entry in the database.", ex);
            return false;
        }
    }

    private boolean ifentry(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws ServletException, IOException {
        try {
            PeerMarkerResult entry = pm_session.getPeerMarkerResult();
            if (entry != null) {
                req.setSwitchedOff(false);
                return true;
            } else {
                req.setSwitchedOff(true);
                return false;
            }

        } catch (Exception ex) {
            logException(null, "PeerMarkerFacility", "ifentry",
                    "Technical error looking for an entry in the database.", ex);
            return false;
        }
    }

    private void peermsiblings(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        PeerMarkerQuestion q;
        Resource sib_resource;
        PeerMarkerSession sib_session;
        Vector questions_in_order;
        Enumeration sibs_enum;
        int papers;

        Vector sibs = pm_session.getPeerMarkerSiblings();
        papers = sibs.size();
        sibs_enum = sibs.elements();
        while (sibs_enum.hasMoreElements()) {
            sib_resource = (PeerMarkerPaper) sibs_enum.nextElement();
            sib_session = (PeerMarkerSession) BuildingSessionManagerImpl
                    .getSession(sib_resource);
            questions_in_order = sib_session.getPeerMarkerQuestionsInOrder();
            for (int i = 0; i < questions_in_order.size(); i++) {
                q = (PeerMarkerQuestion) questions_in_order.elementAt(i);
                peermsummary(req, out, sib_session, sib_resource, q, i + 1,
                        papers == 1);
                out.println("<br/>");
            }
            if (papers == 1)
                out.println("<br/>");
            else
                out.println("<hr/><br/>");
        }

    }

    private void peermsummary(Request req, PrintWriter out,
            PeerMarkerSession pm_session, Resource resource,
            PeerMarkerQuestion q, int item, boolean single_res)
            throws IOException, BuildingServerException {
        PrimaryKey markeeID, markerID, questionID;
        Enumeration markers, markees;
        PeerMarkerPaper paper = pm_session.getPeerMarkerPaper();
        int total, no_of_marks, available, i;
        double average;
        leftpanel = "../bs_template_peermmoderatelist.html";
        rightpanel = "bs_template_peermmoderatepaper.html";
        leftpanel2 = "../bs_template_peermmoderate2list.html";
        rightpanel2 = "bs_template_peermmoderate2paper.html";

        if (req.getUserId() == null) {
            out.println("<pre>"
                    + loc.getString("anonymous.access.is.not.allowed")
                    + "</pre>");
            return;
        }
        if (!BuildingContext.getContext().checkPermission("manage")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.moderate")
                    + "</pre>\n");
            return;
        }

        // count the number of markers - needed for layout
        // put the userIDs into a Vector for later use
        int no_of_markers = 0;
        markers = resource.everyoneWhoCan(Permission.MARK, false);
        Vector markerList = new Vector();
        while (markers.hasMoreElements()) {
            Object obj = (Object) markers.nextElement();
            if (obj instanceof User) {
                no_of_markers++;
                markerList.add(((User) obj).getUserId());
            }
        }

        markees = resource.everyoneWhoCan(Permission.POST, false);

        if ((markerList.size() == 0) || (markees.hasMoreElements() == false)) {

            out.println("<pre>" + loc.getString("no.marks.for.question") + item
                    + ".</pre>");
            out.println("</form>");
            return;

        }

        available = q.getAvailable();
        questionID = q.getPrimaryKey();
        out.println("<table border=\"1\" >");
        out.println("<tr><td><h4>" + resource.getTitle() + "<br/>"
                + loc.getString("item") + item + "</h4></td><td colspan=\""
                + (no_of_markers + 1) + "\"><div align=\"center\"><h4>"
                + loc.getString("markers") + "</h4></div></td></tr>");
        out.print("<tr>");
        out.print("<td>&nbsp;</td>");
        for (i = 0; i < markerList.size(); i++) {
            markerID = (PrimaryKey) markerList.elementAt(i);
            User user = User.findUser(markerID);
            if (single_res)
                out.print("<td><a href=\"../" + resource.getName() + "/"
                        + markerID.toString()
                        + "/bs_template_main1.html\" target=\"buildmain\">"
                        + user.getInitials() + "</a></td>");
            else
                out.print("<td><a href=\"../" + resource.getName() + "/"
                        + markerID.toString()
                        + "/bs_template_index1.html\" target=\"_top\">"
                        + user.getInitials() + "</a></td>");
        }
        out.print("<td>" + loc.getString("average") + "</td>");
        out.println("</tr>");
        while (markees.hasMoreElements()) {
            Object obj2 = (Object) markees.nextElement();
            if (obj2 instanceof User) {
                User markee = (User) obj2;
                markeeID = markee.getUserId();
                out.print("<tr>");

                if (single_res)
                    out.println("<td><a href=\"../" + resource.getName() + "/"
                            + markee.getUserId().toString()
                            + "/bs_template_main2.html\" target=\"buildmain\">"
                            + markee.getName() + "</a></td>");
                else
                    out.println("<td><a href=\"../" + resource.getName() + "/"
                            + markee.getUserId().toString()
                            + "/bs_template_index2.html\" target=\"_top\">"
                            + markee.getName() + "</a></td>");

                total = 0;
                no_of_marks = 0;
                for (i = 0; i < markerList.size(); i++) {
                    markerID = (PrimaryKey) markerList.elementAt(i);
                    PeerMarkerResponse pmr = pm_session.getPeerMarkerResponse(
                            markerID, markeeID, questionID);
                    if (pmr == null)
                        out.print("<td>&nbsp;</td>");
                    else if (pmr.getMarkAllowed() == 0) {
                        out
                                .print("<td><div align=\"center\"><span style=\"color:red\">");
                        out.print(pmr.getMark() + "X");
                        out.print("</span></div></td>");
                    } else if (pmr.getMark().intValue() != pmr
                            .getModeratedMark().intValue()) {
                        total += pmr.getModeratedMark().intValue();
                        no_of_marks++;
                        out
                                .print("<td><div align=\"center\"><span style=\"color:red\">");
                        out.print(pmr.getModeratedMark());
                        out.print("</span></div></td>");
                    } else {
                        total += pmr.getModeratedMark().intValue();
                        no_of_marks++;
                        out.print("<td><div align=\"center\">");
                        out.print(pmr.getModeratedMark());
                        out.print("</div></td>");
                    }

                }
                if (no_of_marks > 0) {
                    average = (double) total / (double) no_of_marks;
                    // round to 2 decimal places
                    BigDecimal bd = new BigDecimal(average);
                    bd = bd.setScale(2, BigDecimal.ROUND_UP);
                    average = bd.doubleValue();
                    out.print("<td>" + average + "/" + available + "</td>");
                } else
                    out.print("<td>&nbsp;</td>");
                out.println("</tr>");
            }
        }

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

    private void peermpaper2(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        PrimaryKey markeeID, uid;
        PeerMarkerQuestion q;
        Resource resource = BuildingContext.getContext().getResource();
        int userno, i;
        String param;
        Vector questions_in_order;
        PeerMarkerPaper paper = pm_session.getPeerMarkerPaper();

        leftpanel = "../bs_template_peermmoderatelist.html";
        rightpanel = "bs_template_peermmoderatepaper.html";

        if (req.getUserId() == null) {
            out.println("<pre>"
                    + loc.getString("anonymous.access.is.not.allowed")
                    + "</pre>");
            return;
        }
        if (!BuildingContext.getContext().checkPermission("manage")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.moderate")
                    + "</pre>\n");
            return;
        }
        if (req.getTemplateParameterCount() < 1) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        param = (String) req.getTemplateParameter(0);
        if (param == null) {
            out.println(loc.getString("invalid.page.address.no.user"));
            return;
        }

        uid = new PrimaryKey(Integer.parseInt(param));

        out.println("<b>" + loc.getString("marks.received.by")
                + User.findUser(uid).getName() + "</b>");
        out
                .println("<form method=\"post\" action=\"bs_template_peermmoderate2confirm.html\">");

        markeeID = new PrimaryKey(Integer.parseInt(param));
        questions_in_order = pm_session.getPeerMarkerQuestionsInOrder();
        for (i = 0; i < questions_in_order.size(); i++) {
            userno = 0;
            q = (PeerMarkerQuestion) questions_in_order.elementAt(i);

            Enumeration enumeration = resource.everyoneWhoCan(Permission.MARK,
                    false);

            if (enumeration.hasMoreElements() == false) {

                out.println("<pre>"
                        + loc.getString("no.users.whose.work.needs.marking")
                        + "</pre>");
                out.println("</form>");
                return;

            } else {

                out.print("<table border=\"1\" width=\"95%\"><tr><td><h4>Item "
                        + (i + 1));
                out.println("</h4></td>");
                out.print("<td colspan=\"3\" rowspan=\"2\" >");
                out.print(loc.getString("disallow.all.marks.for.this.question")
                        + "<input type=\"checkbox\" name=\"DenyAllQ_" + i
                        + "\" value=\"yes\">");
                out.println("</td>");
                out.println("<tr><td>");
                out.println(q.getQuestion());
                out.println("</td></tr>");
                out.println("<input type=\"hidden\" name=\"Question" + i
                        + "\" value=\""
                        + q.getPeerMarkerQuestionId().toString() + "\"/>");

                out.print("<tr><td><b>" + loc.getString("marks.given.by")
                        + "</b></td><td><div align=\"center\"><b>"
                        + loc.getString("mark") + "</b></div></td>");
                // add extras for moderated marks here
                out.println("<td><div align=\"center\"><b>"
                        + loc.getString("moderated") + "</b></div></td>");
                out.println("<td><div align=\"center\"><b>"
                        + loc.getString("disallow") + "</b></div></td>");
                out.println("</tr>");

                userno = 0;
                while (enumeration.hasMoreElements()) {
                    Object obj = (Object) enumeration.nextElement();
                    // everyoneWhoCan() returns both the users and the groups
                    // they belong to

                    if (obj instanceof User) {
                        User user = (User) obj;
                        if ((user.getUserId().intValue() == markeeID.intValue())
                                && (paper.getSelfAllowed() == 0))
                            continue;

                        out.println("<tr>");
                        out
                                .println("<td><a href=\"../"
                                        + user.getUserId().toString()
                                        + "/bs_template_main1.html\" target=\"buildmain\">"
                                        + user.getName() + "</a></td>");

                        PeerMarkerResponse pmr = pm_session
                                .getPeerMarkerResponse(user.getUserId(),
                                        markeeID, q.getPrimaryKey());

                        if (pmr == null)
                            out
                                    .println("<td colspan=\"3\"><div align=\"center\">"
                                            + loc.getString("not.marked")
                                            + "</div></td>");
                        else {
                            out.println("<input type=\"hidden\" name=\"MarkerQ"
                                    + i + "_" + userno + "\" value=\""
                                    + user.getUserId().toString() + "\"/>");
                            out.print("<td><div align=\"center\">"
                                    + pmr.getMark() + "</div></td>");
                            out.println("<td><div align=\"center\">");

                            out.println("<select name=\"ResponseQ" + i + "_"
                                    + userno + "\">");
                            for (int m = 0; m <= q.getAvailable(); m++) {
                                if (pmr.getModeratedMark().intValue() == m)
                                    out.println("<option value=\"" + m
                                            + "\" selected=\"selected\"/>" + m);
                                else
                                    out.println("<option value=\"" + m + "\"/>"
                                            + m);
                            }

                            out.println("</select>");
                            out.println("</div></td>");

                            out
                                    .print("<td><div align=\"center\"><input type=\"checkbox\" name=\"AllowedQ"
                                            + i
                                            + "_"
                                            + userno
                                            + "\" value=\"no\"");
                            if (pmr.getMarkAllowed() == 0)
                                out.print(" checked=\"checked\" ");
                            out.println("/></div></td>");
                            userno++;
                        }
                        out.println("</tr>");

                    }
                }
            }

            out.println("</table>");
            out.println("<input type=\"hidden\" name=\"NO_OF_RESPONSES_" + i
                    + "\" value=\"" + userno + "\"/>");
        }

        out.println("<br/><br/><input type=\"submit\" value=\""
                + loc.getString("save.marks") + "\"/>");

        out.println("<input type=\"hidden\" name=\"Markee\" value=\""
                + uid.toString() + "\"/>");
        out.println("<input type=\"hidden\" name=\"Paper\" value=\""
                + paper.getPeerMarkerPaperId().toString() + "\"/>");
        out.println("<input type=\"hidden\" name=\"NO_OF_QUESTIONS\" value=\""
                + i + "\"/>");

        out.println("</form>");

    }

    // insertname == view, edit, review, moderate, moderate2 or attempt
    private void peermpaper(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String mode) throws IOException,
            BuildingServerException {
        boolean edit, moderate = false, attempt = false, review = false, canmark = false, canseemark = false;
        String param;
        PrimaryKey uid = ((User) BuildingContext.getContext().getUser())
                .getUserId();
        PeerMarkerQuestion q;
        Hashtable responses = null;
        PeerMarkerResult entry = null;
        PeerMarkerResponse response = null;
        PeerMarkerPaper paper = pm_session.getPeerMarkerPaper();
        int i;
        boolean nobutton = false;

        edit = (mode != null && mode.equalsIgnoreCase("edit"));
        moderate = (mode != null && mode.equalsIgnoreCase("moderate"));

        leftpanel2 = "../bs_template_peermmoderate2list.html";
        rightpanel2 = "bs_template_peermmoderate2paper.html";

        Resource resource = BuildingContext.getContext().getResource();
        Vector questions_in_order = pm_session.getPeerMarkerQuestionsInOrder();
        if (questions_in_order.size() == 0) {
            out.println("<hr/>" + loc.getString("no.items.in.this.location")
                    + "</hr>");
            return;
        }

        if (req.getUserId() == null) {
            out.println("<pre>"
                    + loc.getString("anonymous.access.is.not.allowed")
                    + "</pre>");
            return;
        }
        if (mode != null && mode.equalsIgnoreCase("view")) {

            attempt = pm_session.canSubmit();
            review = !attempt;

        }

        if (!edit && !moderate && !attempt && !review) {
            out.println(loc.getString("unknown.presentation.format.selected"));
            return;
        }

        if (edit) {
            if (!BuildingContext.getContext().checkPermission("edit")) {
                out.println("<pre>"
                        + loc.getString("you.dont.have.permission.to.edit")
                        + "</pre>\n");
                return;
            }
            uid = null;
        }

        if (review) {
            if (!BuildingContext.getContext().checkPermission("review")) {
                out.println("<pre>"
                        + loc.getString("you.dont.have.permission.to.review")
                        + "</pre>\n");
                return;
            }
        }

        if (moderate) {
            if (!BuildingContext.getContext().checkPermission("manage")) {
                out.println("<pre>"
                        + loc.getString("you.dont.have.permission.to.moderate")
                        + "</pre>\n");
                return;
            }
            if (req.getTemplateParameterCount() < 1) {
                out.println(loc.getString("invalid.page.address.no.user"));
                return;
            }

            param = (String) req.getTemplateParameter(0);
            if (param == null) {
                out.println(loc.getString("invalid.page.address.no.user"));
                return;
            }

            uid = new PrimaryKey(Integer.parseInt(param));
            entry = pm_session.getPeerMarkerResult(uid);

            if (entry == null) {
                out.println("<hr/>" + loc.getString("this.user.has.not.marked")
                        + "<hr/>");
                return;
            }
        }

        if (!edit)
            out.println("<b>" + loc.getString("marker")
                    + User.findUser(uid).getName() + "</b>");

        if (attempt || review) {
            entry = pm_session.getPeerMarkerResult();
            if ((entry != null)
                    && (entry.getStatus() == PeerMarkerResult.STATUS_MODERATED)) {
                out.println("<h4>" + loc.getString("marks.moderated.by.tutor")
                        + "</h4>");
                out.println("<p>" + loc.getString("moderated.in.italic")
                        + "</p>");
            }
        }

        if (attempt) {
            out
                    .println("<form method=\"post\" action=\"bs_template_peermrecord.html\">");
        }

        if (moderate) {
            out
                    .println("<form method=\"post\" action=\"bs_template_peermmoderateconfirm.html\">");
        }

        for (i = 0; i < questions_in_order.size(); i++) {
            q = (PeerMarkerQuestion) questions_in_order.elementAt(i);

            if (entry != null)
                responses = pm_session.getPeerMarkeeResponses(entry
                        .getPeerMarkerResultId(), q.getPeerMarkerQuestionId());
            else
                responses = new Hashtable();

            out.print("<table border=\"1\" width=\"95%\"><tr><td><h4>"
                    + loc.getString("item") + (i + 1));
            if (edit)
                out.print(" (" + q.getOrdinal() + ")");
            out.println("</h4></td>");
            if (moderate) {
                out.print("<td colspan=\"3\" rowspan=\"2\" >");
                out.print(loc.getString("disallow.all.marks.for.this.question")
                        + "<input type=\"checkbox\" name=\"DenyAllQ_" + i
                        + "\" value=\"yes\">");
                out.println("</td>");

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

            if (edit) {
                out.print("<p><form method=\"post\" action=\"");
                out.print(req.getContextPath());
                out.print(req.getServletPath());
                out.print(resource.getFullName());
                out.print(q.getPeerMarkerQuestionId()
                        + "/bs_template_peermeditq.html\">");
                out.println("<tr><td>");
                out.println(q.getQuestion());
                out.println("</td></tr>");
                out.println("<tr><td>");
                out.println("<input type=\"submit\" value=\""
                        + loc.getString("edit.this.item") + "\"/></form></p>");
                out.println("</td></tr>");
                out.println("</table>");
                continue;
            }

            int userno = 0;
            if (attempt || moderate) {
                out.println("<tr><td>");
                out.println(q.getQuestion());
                out.println("</td></tr>");

                Enumeration enumeration = resource.everyoneWhoCan(
                        Permission.POST, false);

                if (enumeration.hasMoreElements() == false) {
                    out.println("<tr><td>");
                    out
                            .println("<pre>"
                                    + loc
                                            .getString("no.users.whose.work.needs.marking")
                                    + "</pre>");
                    out.println("</td></tr>");
                    nobutton = true;

                } else {

                    out.println("<input type=\"hidden\" name=\"Question" + i
                            + "\" value=\""
                            + q.getPeerMarkerQuestionId().toString() + "\"/>");
                    if (attempt)
                        out.print("<tr><td><b>" + loc.getString("name")
                                + "</b></td><td><b>" + loc.getString("mark")
                                + "</b></td>");
                    else
                        out.print("<tr><td><b>"
                                + loc.getString("marks.given.to")
                                + "</b></td><td><div align=\"center\"><b>"
                                + loc.getString("mark") + "</b></div></td>");
                    // add extras for moderated marks here
                    if (moderate) {
                        out.println("<td><div align=\"center\"><b>"
                                + loc.getString("moderated")
                                + "</b></div></td>");
                        out
                                .println("<td><div align=\"center\"><b>"
                                        + loc.getString("disallow")
                                        + "</b></div></td>");
                    }
                    out.println("</tr>");
                    while (enumeration.hasMoreElements()) {
                        Object obj = (Object) enumeration.nextElement();
                        // everyoneWhoCan() returns both the users and the
                        // groups they belong to

                        if (obj instanceof User) {
                            User user = (User) obj;
                            if ((user.getUserId().intValue() == uid.intValue())
                                    && (paper.getSelfAllowed() == 0))
                                continue;

                            PeerMarkerResponse pmr = (PeerMarkerResponse) responses
                                    .get(user.getUserId());

                            out.println("<tr>");
                            if (attempt) // just show the name
                                out.println("<td>" + user.getName() + "</td>");
                            else
                                // link the name to the appropriate moderate
                                // marks received page
                                out
                                        .println("<td><a href=\"../"
                                                + user.getUserId().toString()
                                                + "/bs_template_main2.html\" target=\"buildmain\">"
                                                + user.getName() + "</a></td>");
                            out.println("<input type=\"hidden\" name=\"USERQ"
                                    + i + "_" + userno + "\" value=\""
                                    + user.getUserId().toString() + "\"/>");

                            if (moderate) {
                                out.print("<td><div align=\"center\">"
                                        + pmr.getMark() + "</div></td>");
                            }

                            out.println("<td><div align=\"center\">");
                            out.println("<select name=\"ResponseQ" + i + "_"
                                    + userno + "\">");
                            for (int m = 0; m <= q.getAvailable(); m++) {
                                if (pmr == null)
                                    out.println("<option value=\"" + m + "\"/>"
                                            + m);
                                else {
                                    if (pmr.getModeratedMark().intValue() == m)
                                        out.println("<option value=\"" + m
                                                + "\" selected=\"selected\"/>"
                                                + m);
                                    else
                                        out.println("<option value=\"" + m
                                                + "\"/>" + m);
                                }
                            }
                            out.println("</select>");
                            out.println("</div></td>");

                            if (moderate) {
                                out
                                        .print("<td><div align=\"center\"><input type=\"checkbox\" name=\"AllowedQ"
                                                + i
                                                + "_"
                                                + userno
                                                + "\" value=\"no\"");
                                if (pmr.getMarkAllowed() == 0)
                                    out.print(" checked=\"checked\" ");
                                out.println("/></div></td>");
                            }
                            out.println("</tr>");

                            userno++;
                        }
                    }
                }
            }

            if (review) {
                out.println("<tr><td>");
                out.println(q.getQuestion());
                out.println("</td></tr>");

                Enumeration enumeration = resource.everyoneWhoCan(
                        Permission.POST, false);
                if (enumeration.hasMoreElements() == false) {
                    out.println("<tr><td>");
                    out.println("<pre>"
                            + loc.getString("no.users.whose.work.was.marked")
                            + "</pre>");
                    out.println("</td></tr>");
                } else {

                    out.print("<tr><td><b>" + loc.getString("name")
                            + "</b></td><td><b>" + loc.getString("mark")
                            + "</b></td>");
                    out.println("</tr>");
                    while (enumeration.hasMoreElements()) {
                        Object obj = (Object) enumeration.nextElement();
                        // everyoneWhoCan() returns both the users and the
                        // groups they belong to

                        if (obj instanceof User) {
                            User user = (User) obj;
                            if ((user.getUserId().intValue() == uid.intValue())
                                    && (paper.getSelfAllowed() == 0))
                                continue;

                            // don't show disallowed marks
                            PeerMarkerResponse pmr = (PeerMarkerResponse) responses
                                    .get(user.getUserId());
                            // if (pmr.getMarkAllowed()==0) continue;

                            int mark = pmr.getMark().intValue();
                            int mod_mark = pmr.getModeratedMark().intValue();
                            boolean disallowed = (pmr.getMarkAllowed() == 0);
                            boolean moderated = (mark != mod_mark);

                            out.println("<tr>");
                            out.print("<td>");
                            if (disallowed || moderated)
                                out.print("<i>");
                            out.print(user.getName());
                            if (disallowed)
                                out.print("</i>");
                            out.println("</td>");

                            out.print("<td>");
                            if (moderated && !disallowed)
                                out.print("<i>" + mark + " -> " + mod_mark
                                        + "</i>");
                            else if (disallowed)
                                out.print("<i>" + loc.getString("disallowed")
                                        + "</i>");
                            else
                                out.print(mod_mark);

                            out.println("</td>");

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

            out.println("</table>");
            out.println("<input type=\"hidden\" name=\"NO_OF_RESPONSES_" + i
                    + "\" value=\"" + userno + "\"/>");

        }
        if (attempt || moderate) {
            if (!nobutton)
                out.println("<br/><br/><input type=\"SUBMIT\" value=\""
                        + loc.getString("save.marks") + "\"/>");

            out.println("<input type=\"hidden\" name=\"Marker\" value=\""
                    + uid.toString() + "\"/>");
            out.println("<input type=\"hidden\" name=\"Paper\" value=\""
                    + paper.getPeerMarkerPaperId().toString() + "\"/>");
            out
                    .println("<input type=\"hidden\" name=\"NO_OF_QUESTIONS\" value=\""
                            + i + "\"/>");

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

    }

    private void peermlist(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        int i, j, status;
        Vector users;
        Hashtable entries;
        User user;
        PeerMarkerResult entry;

        users = pm_session.getPeerMarkerUsers();
        entries = pm_session.getPeerMarkerResults();

        if (users.size() == 0) {
            out.println("<br/><br/>" + loc.getString("no.marks.recorded"));
            return;
        }

        out.println("<table border=\"1\"><tr><td>" + loc.getString("entry")
                + "</td></tr>");

        for (i = 0; i < users.size(); i++) {
            user = (User) users.elementAt(i);
            entry = (PeerMarkerResult) entries.get(user.getUserId());

            if (user == null || entry == null) {
                out.println("<tr><td colspan=\"3\">"
                        + loc.getString("problem.fetching.entry.details")
                        + "</td></tr>");
                continue;
            }

            out.print("<tr><td><a target=\"docmain\" href=\""
                    + entry.getUserId()
                    + "/bs_template_peermmoderatepaper.html\">");

            if (user.getName() == null)
                out.print(loc.getString("no.name"));
            else
                out.print(user.getName());

            out.println("</a></td>");

            out.print("</td></tr>");
        }

        out.println("</table>");

    }

    private void peermlist2(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        int i, j, status;
        Vector users;
        Hashtable entries;
        User user;

        Resource resource = BuildingContext.getContext().getResource();
        Enumeration enumeration = resource.everyoneWhoCan(Permission.POST,
                false);
        if (enumeration.hasMoreElements() == false) {

            out.println("<br/><br/>"
                    + loc.getString("there.are.no.users.whose") + "<br/>"
                    + loc.getString("work.is.available.for.marking"));
            return;
        }
        out.println("<table border=\"1\"><tr><td>" + loc.getString("entry")
                + "</td></tr>");

        while (enumeration.hasMoreElements()) {
            Object obj = (Object) enumeration.nextElement();
            // everyoneWhoCan() returns both the users and the groups they
            // belong to

            if (obj instanceof User) {
                user = (User) obj;
                if (user == null) {
                    out.println("<tr><td colspan=\"3\">"
                            + loc.getString("problem.fetching.entry.details")
                            + "</td></tr>");
                    continue;
                }
                out.print("<tr><td><a target=\"docmain\" href=\""
                        + user.getUserId()
                        + "/bs_template_peermmoderate2paper.html\">");

                if (user.getName() == null)
                    out.print(loc.getString("no.name"));
                else
                    out.print(user.getName());

                out.println("</a></td>");

                out.print("</td></tr>");
            }
        }

        out.println("</table>");

    }

    private void peermrecord(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String insertname)
            throws IOException, BuildingServerException {
        int i, j;
        String param;
        Vector questions_in_order;
        PeerMarkerQuestion q;
        PrimaryKey questionID, markerID, markeeID, userID;
        PeerMarkerResponse responses[][];
        Integer mark;
        int mark_allowed;
        boolean moderated = false;
        String denyAll;

        User user = (User) BuildingContext.getContext().getUser();
        userID = user.getUserId();
        int no_of_responses = Integer.parseInt(req
                .getParameter("NO_OF_RESPONSES_0"));

        questions_in_order = pm_session.getPeerMarkerQuestionsInOrder();
        responses = new PeerMarkerResponse[questions_in_order.size()][no_of_responses];

        markerID = new PrimaryKey(Integer.parseInt(req.getParameter("Marker")));

        for (i = 0; i < questions_in_order.size(); i++) {
            q = (PeerMarkerQuestion) questions_in_order.elementAt(i);
            questionID = q.getPeerMarkerQuestionId();
            denyAll = req.getParameter("DenyAllQ_" + i);

            for (j = 0; j < no_of_responses; j++) {
                markeeID = new PrimaryKey(Integer.parseInt(req
                        .getParameter("USERQ" + i + "_" + j)));
                mark = new Integer(Integer.parseInt(req
                        .getParameter("ResponseQ" + i + "_" + j)));
                String disallowed = req.getParameter("AllowedQ" + i + "_" + j);

                if ((disallowed == null) && (denyAll == null))
                    mark_allowed = 1;
                else {
                    mark_allowed = 0;
                    moderated = true;
                }

                // need to check if record already exists
                responses[i][j] = pm_session.getPeerMarkerResponse(markerID,
                        markeeID, questionID);

                if (responses[i][j] == null) {
                    responses[i][j] = new PeerMarkerResponse();
                    responses[i][j].setPeerMarkerQuestionId(questionID);
                    responses[i][j].setPeerMarkerUserId(markerID);
                    responses[i][j].setPeerMarkeeUserId(markeeID);
                } else if (responses[i][j].getMark().intValue() != mark
                        .intValue())
                    moderated = true;

                if (insertname.equalsIgnoreCase("moderate"))
                    responses[i][j].setModeratedMark(mark);
                else {
                    responses[i][j].setMark(mark);
                    responses[i][j].setModeratedMark(mark);
                }

                responses[i][j].setMarkAllowed(mark_allowed);
            }

        }

        PeerMarkerResult result = pm_session.record(responses,
                questions_in_order.size(), no_of_responses, markerID);
        if (moderated) {
            result.setStatus(PeerMarkerResult.STATUS_MODERATED);
            result.save();
        }

        if (insertname.equalsIgnoreCase("moderate"))
            out.println(loc.getString("moderated.marks.saved"));
        else {
            out.println("<p>"
                    + loc.getString("thank.you.for.recording.your.marks")
                    + "</p>");
            if (req.getUserId() == null)
                out.println("<p>"
                        + loc.getString("they.were.recorded.anonymously")
                        + "</p>");
            else {
                out.println("<p>"
                        + loc.getString("they.were.recorded.under.the.name")
                        + user.getName() + ".</p>");
                out
                        .println("<p>"
                                + loc.getString("your.marks.may.be.moderated")
                                + "</p>");
            }
        }
        Event event = new AssessmentEvent(AssessmentEvent.EVENT_SUBMIT_MARKS,
                req.getResource().getResourceId(), req.getUserId(), null,
                new Integer(result.getPeerMarkerResultId().intValue()), null);
        event.save();
    }

    private void peermrecord2(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        int i, j;
        String param;
        Vector questions_in_order;
        PeerMarkerQuestion q;
        PrimaryKey questionID, markerID, markeeID, userID;
        PeerMarkerResponse responses[][];
        PeerMarkerResult result;
        Integer mark;
        int mark_allowed;
        boolean moderated = false;
        String denyAll;

        User user = (User) BuildingContext.getContext().getUser();
        userID = user.getUserId();

        int no_of_responses = Integer.parseInt(req
                .getParameter("NO_OF_RESPONSES_0"));

        questions_in_order = pm_session.getPeerMarkerQuestionsInOrder();
        responses = new PeerMarkerResponse[questions_in_order.size()][no_of_responses];

        markeeID = new PrimaryKey(Integer.parseInt(req.getParameter("Markee")));

        for (i = 0; i < questions_in_order.size(); i++) {
            q = (PeerMarkerQuestion) questions_in_order.elementAt(i);
            questionID = q.getPeerMarkerQuestionId();
            denyAll = req.getParameter("DenyAllQ_" + i);

            for (j = 0; j < no_of_responses; j++) {
                markerID = new PrimaryKey(Integer.parseInt(req
                        .getParameter("MarkerQ" + i + "_" + j)));

                mark = new Integer(Integer.parseInt(req
                        .getParameter("ResponseQ" + i + "_" + j)));
                String disallowed = req.getParameter("AllowedQ" + i + "_" + j);

                if ((disallowed == null) && (denyAll == null))
                    mark_allowed = 1;
                else {
                    mark_allowed = 0;
                    moderated = true;
                }

                // need to check if record already exists
                responses[i][j] = pm_session.getPeerMarkerResponse(markerID,
                        markeeID, questionID);

                if (responses[i][j] == null) {
                    responses[i][j] = new PeerMarkerResponse();
                    responses[i][j].setPeerMarkerQuestionId(questionID);
                    responses[i][j].setPeerMarkerUserId(markerID);
                    responses[i][j].setPeerMarkeeUserId(markeeID);
                } else {
                    if (responses[i][j].getMark().intValue() != mark.intValue())
                        moderated = true;
                    if ((responses[i][j].getMarkAllowed() == 0)
                            && (disallowed == null))
                        moderated = true;
                }
                responses[i][j].setModeratedMark(mark);
                responses[i][j].setMarkAllowed(mark_allowed);
                responses[i][j].save();

                if (moderated) {
                    result = PeerMarkerResult
                            .findPeerMarkerResult(responses[i][j]
                                    .getPeerMarkerResultId());
                    result.setStatus(PeerMarkerResult.STATUS_MODERATED);
                    result.save();
                }
            }

        }

        out.println(loc.getString("moderated.marks.saved"));

    }

    private void peermnewitem(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String insertname) throws IOException {
        try {
            pm_session.createQuestion();
        } catch (Exception ex) {
            out.println("<hr/>" + loc.getString("problem.creating.item")
                    + "<hr/>" + ex.getMessage());
        }
    }

    private void peermitemedit(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String insertname)
            throws IOException, BuildingServerException {
        String id;
        Hashtable questions;
        PeerMarkerQuestion question;

        if (!BuildingContext.getContext().checkPermission("edit")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.edit")
                    + "</pre>\n");
            return;
        }

        // must have an id in the parameter part of the URL
        if (req.getTemplateParameterCount() < 1) {
            out.println("<i>" + loc.getString("cant.display.edit.field")
                    + "</i>");
            return;
        }
        id = (String) req.getTemplateParameter(0);

        questions = pm_session.getPeerMarkerQuestions();
        if (questions == null) {
            out.println("<i>" + loc.getString("cant.display.edit.field")
                    + "</i>");
            return;
        }

        question = (PeerMarkerQuestion) questions.get(new PrimaryKey(Integer
                .parseInt(id)));

        if (question == null) {
            out.println("<i>" + loc.getString("cant.display.edit.field")
                    + "</i>");
            return;
        }

        if (insertname.equalsIgnoreCase("ordinal")) {
            out.println("<input name=\"ordinal\" value=\""
                    + question.getOrdinal() + "\"/>");
            return;
        }

        if (insertname.equalsIgnoreCase("available")) {
            out.println("<input name=\"available\" value=\""
                    + question.getAvailable() + "\"/>");

            return;
        }

        if (insertname.equalsIgnoreCase("question")) {
            out
                    .print("<span class=\"bs-textarea\"><textarea name=\"question\" cols=\"45\" rows=\"8\">");
            out.print(question.getQuestion());
            out.println("</textarea></span>");
            return;
        }

    }

    private void peermeditqconfirm(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String insertname)
            throws IOException, BuildingServerException {
        int n;
        String id, param;
        PrimaryKey qid;
        Hashtable questions;
        PeerMarkerQuestion q;

        if (!BuildingContext.getContext().checkPermission("edit")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.edit")
                    + "</pre>\n");
            return;
        }

        // must have an id in the parameter part of the URL
        if (req.getTemplateParameterCount() < 1) {
            out.println("<i>" + loc.getString("cant.display.edit.field")
                    + "</i>");
            return;
        }
        id = (String) req.getTemplateParameter(0);
        qid = new PrimaryKey(Integer.parseInt(id));

        questions = pm_session.getPeerMarkerQuestions();
        q = (PeerMarkerQuestion) questions.get(qid);

        if (q == null) {
            out.println("<i>" + loc.getString("cant.display.edit.field")
                    + "</i>");
            return;
        }

        param = req.getParameter("ordinal");
        try {
            q.setOrdinal(Integer.parseInt(param));
        } catch (NumberFormatException ex) {
            out.println("<hr/>"
                    + loc.getString("invalid.number.in.ordinal.field")
                    + "<hr/>");
            return;
        }

        param = req.getParameter("available");
        try {
            int a = Integer.parseInt(param);
            if (a < 1 || a > 100) {
                out.println(loc.getString("available.mark.must.be.between"));
                return;
            }
            q.setAvailable(a);
        } catch (NumberFormatException ex) {
            out.println("<hr/>"
                    + loc.getString("invalid.number.in.available.marks.field")
                    + "<hr/>");
            return;
        }

        pm_session.changeQuestionText(q.getPeerMarkerQuestionId(), q
                .getQuestionBigStringId(), req.getParameter("question"));

        pm_session.changeQuestion(q.getPeerMarkerQuestionId(), q);

        out.println("<hr/>" + loc.getString("item.saved") + "<hr/>");

    }

    private void peermdeleteq(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException,
            BuildingServerException {
        int n;
        String id, param, notparam;
        PrimaryKey qid;

        if (!BuildingContext.getContext().checkPermission("edit")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.delete")
                    + "</pre>\n");
            return;
        }

        // must have an id in the parameter part of the URL
        if (req.getTemplateParameterCount() < 1) {
            out.println("<i>" + loc.getString("cant.delete.question") + "</i>");
            return;
        }
        id = (String) req.getTemplateParameter(0);
        qid = new PrimaryKey(Integer.parseInt(id));

        param = req.getParameter("confirm");
        if (param == null)
            param = "";
        notparam = req.getParameter("notconfirm");
        if (notparam == null)
            notparam = "";
        if (param.length() < 1 || notparam.length() > 0) {
            out.println("<hr/>" + loc.getString("wrong.checkboxes.selected")
                    + "<hr/>");
            return;
        }

        try {
            pm_session.removeQuestion(qid);
        } catch (BuildingServerException bse) {
            out.println(loc.getString("cant.delete.marked.item"));
        }
    }

    private void peermrunbutton(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException {

        out
                .println("<input name=\"run\" type=\"button\" onclick=\"launchtest()\" value=\""
                        + loc.getString("show.items.now") + "\"/>");

        return;
    }

    private void peermfield(Request req, PrintWriter out,
            PeerMarkerSession pm_session, String name) throws ServletException,
            IOException, BuildingServerException {
        if (!BuildingContext.getContext().checkPermission("manage")) {
            out.println("<pre>"
                    + loc.getString("you.dont.have.permission.to.manage")
                    + "</pre>\n");
            return;
        }

        PeerMarkerPaper paper = pm_session.getPeerMarkerPaper();

        if (name.equalsIgnoreCase("once_only")) {
            out.print("<input type=\"checkbox\" ");
            if (paper.getOnceOnly() == 1)
                out.print("checked=\"checked\" ");
            out
                    .print("name=\"once_only\" value=\"yes\"/>"
                            + loc.getString("marking.allowed.only.once")
                            + "<br/><br/>");
            return;
        }
        if (name.equalsIgnoreCase("self_allowed")) {
            out.print("<input type=\"checkbox\" ");
            if (paper.getSelfAllowed() == 1)
                out.print("checked ");
            out.print("name=\"self_allowed\" value=\"yes\"/>"
                    + loc.getString("marking.self.allowed") + "<br/><br/>");
            return;
        }

        return;
    }

    private void peermmodify(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws ServletException, IOException,
            BuildingServerException {
        String OnceOnly, SelfAllowed;
        int once_only, self_allowed;

        OnceOnly = req.getParameter("once_only");
        if (OnceOnly != null) {
            if (OnceOnly.equalsIgnoreCase("yes"))
                once_only = 1;
            else
                once_only = 0;
        } else
            once_only = 0;
        pm_session.getPeerMarkerPaper().setOnceOnly(once_only);

        SelfAllowed = req.getParameter("self_allowed");
        if (SelfAllowed != null) {
            if (SelfAllowed.equalsIgnoreCase("yes"))
                self_allowed = 1;
            else
                self_allowed = 0;
        } else
            self_allowed = 0;
        pm_session.getPeerMarkerPaper().setSelfAllowed(self_allowed);

        out.println("<p>" + loc.getString("options.saved") + "</p>");

    }

    private void exportCSV(Request req, PrintWriter out,
            PeerMarkerSession pm_session) throws IOException {
        if (BuildingContext.getContext().checkPermission("manage")) {
            out.flush();
            out.println("<p>" + loc.getString("csv.file.created")
                    + "<a href=bs_virtual_marks.csv>"
                    + loc.getString("download") + "</a> "
                    + loc.getString("now") + "</p>");
            out.println("<p>" + loc.getString("left.click.to.view") + "</p>");
        } else
            out.println("<p>" + loc.getString("no.permission.to.view.csv"));

    }
}
