View Javadoc

1   /***
2    * 
3    */
4   package org.telscenter.pas.steps;
5   
6   import java.awt.BorderLayout;
7   import java.awt.Color;
8   import java.awt.Component;
9   import java.awt.event.MouseEvent;
10  import java.awt.event.MouseListener;
11  import java.beans.beancontext.BeanContextServices;
12  import java.io.IOException;
13  import java.io.StringReader;
14  import java.util.ArrayList;
15  import java.util.HashMap;
16  import java.util.List;
17  import java.util.Map;
18  import java.util.TooManyListenersException;
19  import java.util.logging.Level;
20  import java.util.logging.Logger;
21  
22  import javax.swing.BorderFactory;
23  import javax.swing.JComponent;
24  import javax.swing.JLabel;
25  import javax.swing.JPanel;
26  import javax.swing.JScrollPane;
27  import javax.swing.JTextArea;
28  import javax.swing.border.CompoundBorder;
29  
30  import net.miginfocom.swing.MigLayout;
31  import net.sf.sail.core.beans.service.AgentService;
32  import net.sf.sail.core.beans.service.AnnotationService;
33  import net.sf.sail.core.beans.service.SessionService;
34  import net.sf.sail.core.entity.AgentSet;
35  import net.sf.sail.core.entity.IAgent;
36  import net.sf.sail.core.entity.ISock;
37  import net.sf.sail.core.entity.MismatchedAgentSetSizeException;
38  import net.sf.sail.core.entity.Rim;
39  import net.sf.sail.core.entity.Role;
40  import net.sf.sail.core.entity.User;
41  
42  import org.telscenter.pas.beans.IWorkReporter;
43  import org.telscenter.pas.beans.PasStep;
44  import org.telscenter.pas.common.ui.CommonUI;
45  import org.telscenter.pas.service.NavigateAction;
46  import org.telscenter.pas.steps.domain.AssessmentItem;
47  import org.telscenter.pas.steps.domain.BlockInteraction;
48  import org.telscenter.pas.steps.domain.ChoiceInteraction;
49  import org.telscenter.pas.steps.domain.ResponseDeclaration;
50  import org.telscenter.pas.steps.domain.SimpleChoice;
51  import org.telscenter.pas.ui.pdf.PDFUtil;
52  import org.telscenter.pas.ui.util.PasColors;
53  import org.telscenter.pas.util.AnnotationUtils;
54  
55  import com.lowagie.text.Element;
56  import com.lowagie.text.Font;
57  import com.lowagie.text.Paragraph;
58  import com.lowagie.text.Phrase;
59  import com.lowagie.text.html.simpleparser.HTMLWorker;
60  import com.lowagie.text.html.simpleparser.StyleSheet;
61  import com.lowagie.text.pdf.PdfPCell;
62  import com.lowagie.text.pdf.PdfPTable;
63  
64  /***
65   * @author aperritano
66   * 
67   */
68  abstract public class Assessment extends PasStep implements IWorkReporter {
69  
70  	private static final Logger logger = Logger.getLogger(Assessment.class
71  			.getName());
72  
73  	public AssessmentItem assessmentItem;
74  
75  	protected transient Map<ResponseDeclaration, ISock<String>> responseDeclarationToSocks = new HashMap<ResponseDeclaration, ISock<String>>();
76  
77  	// responseIdentifier String to ResponseDeclaration
78  	protected transient Map<String, Object> responses = new HashMap<String, Object>();
79  
80  	protected transient AgentService agentService;
81  
82  	protected transient SessionService sessionService;
83  
84  	private List<JPanel> currentStepParts;
85  
86  	private List<String> currentPrompts;
87  
88  	private List<JLabel> answer;
89  	
90  	private boolean injectPrompt;
91  	
92  	private Integer possibleScore;
93  	
94  	private boolean isTabbed = false;
95  	
96  	private boolean submitted = false;
97  	
98  	public void initStepParts(){
99  		this.currentPrompts = new ArrayList<String>();
100 		this.currentStepParts = new ArrayList<JPanel>();
101 		this.answer = new ArrayList<JLabel>();
102 	}
103 	
104 	protected void consumeService(BeanContextServices bcs, Class<? extends Object> serviceClass) {
105 		if (serviceClass == SessionService.class) {
106 			try {
107 				sessionService = (SessionService) bcs.getService(this, this,
108 						SessionService.class, this, this);
109 			} catch (TooManyListenersException e) {
110 				// TODO Auto-generated catch block
111 				logger
112 						.severe("BeanContextServices, Class -  : exception: " + e); //$NON-NLS-1$
113 			}
114 		} else if (serviceClass == AgentService.class) {
115 			try {
116 				agentService = (AgentService) bcs.getService(this, this,
117 						AgentService.class, this, this);
118 			} catch (TooManyListenersException e) {
119 				// TODO Auto-generated catch block
120 				logger
121 						.severe("BeanContextServices, Class -  : exception: " + e); //$NON-NLS-1$
122 			}
123 
124 		}
125 
126 		if (agentService != null && sessionService != null)
127 			bindResponsesToSocks();
128 	}
129 
130 /************************************** SAVING DATA ***********************************************************/	
131 	/*
132 	 * bindResponsesToSocks
133 	 * lastAnswer
134 	 * saveAssessmentItem
135 	 * saveData
136 	 */
137 	
138 	/***
139 	 * Binds response id to socks
140 	 */
141 	protected void bindResponsesToSocks() {
142 		User user = sessionService.getUsers().iterator().next();
143 		AgentSet agentsOfUser = agentService.getAgentsOfUser(user);
144 		AgentSet agentsOfUserInWorkgroup = agentsOfUser
145 				.select(Role.RUN_WORKGROUP);
146 		IAgent agent;
147 		try {
148 			agent = agentsOfUserInWorkgroup.getSingle();
149 		} catch (MismatchedAgentSetSizeException e1) {
150 			logger.severe("exception: " + e1); //$NON-NLS-1$
151 			return;
152 		}
153 
154 		// key: responseID, id of the the choosen response
155 		
156 		if( assessmentItem == null)
157 			return;
158 		
159 
160 		if( assessmentItem
161 				.getResponseDeclarations() != null ) {
162 			List<ResponseDeclaration> responseDeclarations = assessmentItem
163 			.getResponseDeclarations();
164 			for (ResponseDeclaration rd : responseDeclarations) {
165 				Rim<String> rim = rd.getRim();
166 				if (rim != null) {
167 					
168 					try {
169 						ISock<String> sock = agentService.getSock(rim, agent);
170 						responseDeclarationToSocks.put(rd, sock);
171 	
172 						if (!sock.isEmpty()) {
173 							//we have submitted before
174 							submitted= true;
175 							responses.put(rd.getIdentifier(), sock.peek());
176 						}// if
177 					} catch (Exception e) {
178 						logger.severe("exception: " + e); //$NON-NLS-1$
179 					}// try
180 				}// if
181 			}// for
182 		}// if
183 	}
184 
185 
186 
187 	/***
188 	 * @param rd
189 	 * @return
190 	 */
191 	public static String lastAnswer(
192 			Map<ResponseDeclaration, ISock<String>> responseDeclarationToSocks,
193 			final ResponseDeclaration rd) {
194 		final ISock<String> sock = responseDeclarationToSocks.get(rd);
195 
196 		if (sock == null || sock.isEmpty())
197 			return null;
198 
199 		return sock.peek();
200 	}
201 
202 	
203 
204 	/***
205 	 * @param assessmentItem
206 	 *            TODO
207 	 * @param responses
208 	 *            TODO
209 	 * @param responseDeclarationToSocks
210 	 *            TODO
211 	 */
212 	public static void saveAssessmentItem(AssessmentItem assessmentItem,
213 			Map<String, Object> responses,
214 			Map<ResponseDeclaration, ISock<String>> responseDeclarationToSocks) {
215 		List<ResponseDeclaration> reponseDeclarations = assessmentItem
216 				.getResponseDeclarations();
217 
218 		for (ResponseDeclaration rd : reponseDeclarations) {
219 			Object responseContent = responses.get(rd.getIdentifier());
220 
221 			// no choice for the responseDeclaration
222 			if (responseContent == null) {
223 				StudentAssessment.logger
224 						.severe("no response for declaration " + rd.getIdentifier() + " -  : exception: " + null); //$NON-NLS-1$ //$NON-NLS-2$
225 				continue;
226 			}// if
227 
228 			ISock<String> sock = responseDeclarationToSocks.get(rd);
229 			if (sock == null) {
230 				StudentAssessment.logger
231 						.severe("no sock for " + rd + " -  : exception: " + null); //$NON-NLS-1$ //$NON-NLS-2$ 
232 				continue;
233 			}// if
234 
235 			if (responseContent instanceof SimpleChoice) {
236 				SimpleChoice<String> simpleChoice = (SimpleChoice<String>) responseContent;
237 				// HACK REQUESTED BY STEVE BANNASCH
238 				saveData(responseDeclarationToSocks, rd, sock, simpleChoice
239 						.getIdentifier());
240 			} else if (responseContent instanceof String) {
241 				// HACK REQUESTED BY STEVE BANNASCH
242 				saveData(responseDeclarationToSocks, rd, sock, (String) responseContent);
243 			} else {
244 				throw new RuntimeException("unsupported choice type " //$NON-NLS-1$
245 						+ responseContent);
246 			}// if
247 		}
248 	}
249 
250 	public static void saveData(
251 			Map<ResponseDeclaration, ISock<String>> responseDeclarationToSocks,
252 			ResponseDeclaration rd, ISock<String> sock, String data) {
253 
254 		if (sock.isEmpty() == false && sock.peek() != null) {
255 			if (data.equals(sock.peek())) {
256 				logger.warning("DUPICATE ASSESSMENT ENTRY DATA NOT SAVED");
257 				return;
258 			}// if
259 		}// if
260 
261 		sock.add(data);
262 		logger.info("ASSESSMENT ENTRY DATA SAVED");
263 		responseDeclarationToSocks.put(rd, sock);
264 
265 	}
266 
267 /*****************************************************************************************************************/	
268 
269 	/***
270 	 * @return itemPanel
271 	 */
272 	private JPanel createEmptyReportPanel() {
273 		JPanel itemPanel = new JPanel(); 
274 		itemPanel.setLayout(new BorderLayout(0, 0));
275 		itemPanel.setOpaque(false);
276 		JLabel noNoteTakenLabel = createNoNoteTakenLabel();
277 		itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
278 		return itemPanel;
279 	}
280 	
281 	/***
282 	 * @return label
283 	 */
284 	private JLabel createNoNoteTakenLabel() {
285 		JLabel noNoteTakenLabel = new JLabel(Messages
286 				.getString("Note.NOTE_NOT_TAKEN")); //$NON-NLS-1$
287 		noNoteTakenLabel.setFont(noNoteTakenLabel.getFont().deriveFont(
288 				14.0f));
289 		noNoteTakenLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0,
290 				0));
291 		noNoteTakenLabel.setOpaque(false);
292 		return noNoteTakenLabel;
293 	}
294 	
295 	private String getAnswer(ResponseDeclaration rd, BlockInteraction bi){
296 		String answer = lastAnswer(
297 				this.getResponseDeclarationToSocks(), rd);
298 				
299 		if (answer == null || answer.trim() == "") {
300 			answer = Messages.getString("Note.NOT_ANSWERED"); //$NON-NLS-1$
301 	
302 		} else if (bi instanceof ChoiceInteraction) {
303 			ChoiceInteraction<String> ci = (ChoiceInteraction<String>) bi;
304 
305 			List<SimpleChoice<String>> simpleChoices = ci.getSimpleChoices();
306 			for (SimpleChoice<String> sc : simpleChoices) {
307 				if (sc.getIdentifier().equals(answer)) {
308 					answer = sc.getContent();
309 				}
310 			}
311 		}
312 		return answer;
313 	}
314 	
315 	
316 	/***
317 	 * @param htmlPromptPanel
318 	 * @param answer
319 	 * @param navigateAction 
320 	 * @return
321 	 */
322 	private JPanel createAnswerAreaWithOUTAnnotations(JComponent htmlPromptPanel, String answer, final NavigateAction navigateAction) {
323 
324 		JPanel commentPanel = new JPanel(new BorderLayout(0,0));
325 		
326 		JTextArea textArea = new JTextArea(0, 0);
327 		
328 		textArea.setSize(400, textArea.getPreferredSize().height);
329 		textArea.setLineWrap(true);
330 		textArea.setWrapStyleWord(true);
331 		textArea.setEditable(false);
332 		//when the user clicks on the panel it should take them to the step
333 		textArea.setName("answerArea");
334 		textArea.setText(answer);
335 		
336 		commentPanel.add(new JScrollPane(textArea),BorderLayout.CENTER);
337 		commentPanel.setBackground(Color.BLUE);
338 		
339 		if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
340 			textArea.setForeground(Color.RED);
341 			
342 		}else{
343 			textArea.setForeground(Color.BLACK);				
344 		}
345 		
346 		if( navigateAction != null ) {
347 		textArea.addMouseListener(new MouseListener(){
348 
349 			public void mouseClicked(MouseEvent e) {
350 				navigateAction.actionPerformed(null);
351 				
352 			}
353 
354 			public void mouseEntered(MouseEvent e) {
355 				// TODO Auto-generated method stub
356 				
357 			}
358 
359 			public void mouseExited(MouseEvent e) {
360 				// TODO Auto-generated method stub
361 				
362 			}
363 
364 			public void mousePressed(MouseEvent e) {
365 				// TODO Auto-generated method stub
366 				
367 			}
368 
369 			public void mouseReleased(MouseEvent e) {
370 				// TODO Auto-generated method stub
371 				
372 			}});
373 		}
374 		return commentPanel;
375 	}
376 	
377 	
378 	/***
379 	 * @param htmlPromptPanel
380 	 * @param answer
381 	 * @param navigateAction 
382 	 * @return
383 	 */
384 	private JPanel createAnswerAreaWithAnnotations(JComponent htmlPromptPanel, String answer, final NavigateAction navigateAction) {
385 
386 		
387 		JPanel commentPanel = new JPanel(new BorderLayout(0,0));
388 		
389 		JTextArea textArea = new JTextArea(0, 0);
390 		
391 		textArea.setSize(400, textArea.getPreferredSize().height);
392 		textArea.setLineWrap(true);
393 		textArea.setWrapStyleWord(true);
394 		textArea.setEditable(false);
395 		
396 		textArea.setText(answer);
397 		
398 		commentPanel.add(new JScrollPane(textArea),BorderLayout.CENTER);
399 		commentPanel.setBackground(Color.BLUE);
400 		
401 		if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
402 			textArea.setForeground(Color.RED);
403 		}else{
404 			textArea.setForeground(Color.BLACK);				
405 		}
406 		textArea.addMouseListener(new MouseListener(){
407 
408 			public void mouseClicked(MouseEvent e) {
409 				navigateAction.actionPerformed(null);
410 			}
411 
412 			public void mouseEntered(MouseEvent e) {
413 				// TODO Auto-generated method stub
414 				
415 			}
416 
417 			public void mouseExited(MouseEvent e) {
418 				// TODO Auto-generated method stub
419 				
420 			}
421 
422 			public void mousePressed(MouseEvent e) {
423 				// TODO Auto-generated method stub
424 				
425 			}
426 
427 			public void mouseReleased(MouseEvent e) {
428 				// TODO Auto-generated method stub
429 				
430 			}});
431 		return commentPanel;
432 	}
433 	
434 	/*
435 	 * This method creates a text answer for the answer to be stored into. If the step item
436 	 * has not been answered yet, the answer is shown in red; otherwise it is shown in black
437 	 * @param answer
438 	 * @return answerArea 
439 	 */
440 	private JTextArea getAnswerArea(String answer){
441 		JTextArea answerArea = new JTextArea(50, 300);
442 		answer = wrapInlineText(answer, 100);
443 		answer = extractBody(answer);
444 		answerArea.setText(answer);
445 		answerArea.setOpaque(true);
446 		answerArea.setBackground(PasColors.noteReportTextAreaColor);	
447 		if(answer.indexOf( Messages.getString("Note.NOT_ANSWERED")) > -1){
448 			answerArea.setForeground(Color.RED);
449 		}else if (answer == null || answer.trim() == "") {
450 			answer = Messages.getString("Note.NOT_ANSWERED"); //$NON-NLS-1$
451 			answerArea.setForeground(Color.RED);
452 		}else{
453 			answerArea.setForeground(Color.BLACK);				
454 		}
455 				
456 		answerArea.setBorder(CommonUI.createEtchedBorder());
457 		answerArea.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
458 		return answerArea;
459 		
460 	}
461 	
462 	private String wrapInlineText(String inlineFeedbackText, int adjustedWidth){
463 		String initHtml = "<html><body>";
464 		String finalHtml = "</body></html>";
465 		String finalStr = "";	
466 		int lastIndex = 0;
467 
468 		inlineFeedbackText = inlineFeedbackText.trim();
469 
470 		// scytacki: added a limit so if the width is less than 10 there is no point in wrapping the text
471 		if(adjustedWidth > 10){		
472 			// FIXME: if the lastIndex is -1 then the code breaks.  This will happen if there are no spaces in the inlineFeedbackText string.
473 			while(inlineFeedbackText.length() > adjustedWidth){
474 				String substri = inlineFeedbackText.substring(0,adjustedWidth);
475 				lastIndex = substri.lastIndexOf(" ");
476 				finalStr = finalStr + substri.substring(0,lastIndex) + "\n";
477 				inlineFeedbackText = inlineFeedbackText.substring((int)lastIndex, inlineFeedbackText.length());
478 
479 			}
480 		}
481 		
482 		return initHtml + finalStr + inlineFeedbackText.substring(0,inlineFeedbackText.length()) + finalHtml;		
483 	}
484 
485 	/***
486 	 * 
487 	 * Extracts the text in between the <body>...</body>
488 	 */
489 	protected String extractBody(String prompt) {
490 		int start = prompt.indexOf("<body>");
491 		int end = prompt.indexOf("</body>");
492 	
493 		String extractedBody = "";
494 		
495 		if (start != -1 && end != -1) {
496 			extractedBody = prompt.substring(start+6, end);
497 			return extractedBody;
498 		}			
499 		return prompt;
500 	}
501 	
502 	
503 
504 /********************************************************************************************************************/	
505 /**********************************  REPORT FOR LEARNER *************************************************************/	
506 	/*
507 	 * getReportForLearner
508 	 * getReportForLearnerPDF
509 	 * getReportForLearnerWithAnnotations
510 	 */
511 
512 	/***
513 	 * Assessment needs to navigate back to its step with an part of its component has been clicked on
514 	 * 
515 	 * @param NavigateAction - the ability to go to a step
516 	 * 
517 	 */
518 	public JPanel getReportForLearner(final org.telscenter.pas.service.NavigateAction navigateAction) {
519 		
520 		if (logger.isLoggable(Level.CONFIG)) {
521 			logger.config("start"); //$NON-NLS-1$
522 		}
523 
524 		JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
525 		
526 		rootPanel.setBackground(PasColors.showReportsActivityBackgroundColor);
527 		JPanel panel = new JPanel();
528 		panel.setBackground(PasColors.showReportsActivityBackgroundColor);
529 		MigLayout m1 = new MigLayout("insets 0 4 0 0");
530 		panel.setLayout(m1);
531 		
532 		List<ResponseDeclaration> responseDeclarations = assessmentItem
533 				.getResponseDeclarations();
534 
535 		if (responseDeclarations.isEmpty()) {
536 			JPanel itemPanel = createEmptyReportPanel();
537 			panel.add(itemPanel);
538 		} else {
539 			int iterator = 1;
540 			String oldPrompt="";
541 			
542 			for (ResponseDeclaration rd : responseDeclarations) {
543 				BlockInteraction bi = getInteractionByResponseDeclaration(rd);
544 				oldPrompt = bi.getPrompt();
545 				setBiPrompt(responseDeclarations, iterator, bi);				
546 				iterator++;
547 				
548 				JComponent htmlPromptPanel = AssessmentUI.createPromptPanel(bi);
549 				bi.setPrompt(oldPrompt);
550 				JPanel questionAnswerPanel = new JPanel();
551 				questionAnswerPanel.setLayout(new BorderLayout(0, 0));
552 
553 				String answer = getAnswer(rd,bi);
554 				
555 				JPanel answerArea = createAnswerAreaWithOUTAnnotations(htmlPromptPanel, answer, navigateAction);
556 				
557 				//when the user clicks on the panel it should take them to the step
558 				htmlPromptPanel.addMouseListener(new MouseListener(){
559 
560 					public void mouseClicked(MouseEvent e) {
561 						navigateAction.actionPerformed(null);
562 						
563 					}
564 
565 					public void mouseEntered(MouseEvent e) {
566 						// TODO Auto-generated method stub
567 						
568 					}
569 
570 					public void mouseExited(MouseEvent e) {
571 						// TODO Auto-generated method stub
572 						
573 					}
574 
575 					public void mousePressed(MouseEvent e) {
576 						// TODO Auto-generated method stub
577 						
578 					}
579 
580 					public void mouseReleased(MouseEvent e) {
581 						// TODO Auto-generated method stub
582 						
583 					}});
584 				
585 				
586 				questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
587 				questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
588 		
589 				questionAnswerPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1));
590 				panel.add(questionAnswerPanel, "wrap");
591 				CompoundBorder compoundBorder = createCompoundBorder();
592 				//panel.setBorder(compoundBorder);
593 				
594 				
595 				
596 			}
597 		}
598 		rootPanel.add(panel, BorderLayout.CENTER);
599 
600 		if (logger.isLoggable(Level.CONFIG)) {
601 			logger.config("end"); //$NON-NLS-1$
602 		}
603 		return rootPanel;
604 	};
605 	
606 	/***
607 	 * Not needed any more use the one with navigation action
608 	 * 
609 	 */
610 	public JPanel getReportForLearner() {
611 		if (logger.isLoggable(Level.CONFIG)) {
612 			logger.config("start"); //$NON-NLS-1$
613 		}
614 
615 		JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
616 		
617 		rootPanel.setBackground(PasColors.showReportsActivityBackgroundColor);
618 		JPanel panel = new JPanel();
619 		panel.setBackground(PasColors.showReportsActivityBackgroundColor);
620 		MigLayout m1 = new MigLayout("insets 0 4 0 0");
621 		panel.setLayout(m1);
622 		
623 		List<ResponseDeclaration> responseDeclarations = assessmentItem
624 				.getResponseDeclarations();
625 
626 		if (responseDeclarations.isEmpty()) {
627 			JPanel itemPanel = createEmptyReportPanel();
628 			panel.add(itemPanel);
629 		} else {
630 			int iterator = 1;
631 			String oldPrompt="";
632 			
633 			for (ResponseDeclaration rd : responseDeclarations) {
634 				BlockInteraction bi = getInteractionByResponseDeclaration(rd);
635 				oldPrompt = bi.getPrompt();
636 				setBiPrompt(responseDeclarations, iterator, bi);				
637 				iterator++;
638 				
639 				JComponent htmlPromptPanel = AssessmentUI.createPromptPanel(bi);
640 				bi.setPrompt(oldPrompt);
641 				JPanel questionAnswerPanel = new JPanel();
642 				questionAnswerPanel.setLayout(new BorderLayout(0, 0));
643 
644 				String answer = getAnswer(rd,bi);
645 				
646 				JPanel answerArea = createAnswerAreaWithOUTAnnotations(htmlPromptPanel, answer, null);
647 				
648 				//htmlPromptPanel.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
649 				
650 				//when the user clicks on the panel it should take them to the step
651 				htmlPromptPanel.setName("promptPanel");
652 				questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
653 				questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
654 		
655 				questionAnswerPanel.setBorder(BorderFactory.createLineBorder(Color.black, 1));
656 				panel.add(questionAnswerPanel, "wrap");
657 				CompoundBorder compoundBorder = createCompoundBorder();
658 				//panel.setBorder(compoundBorder);
659 				
660 				
661 				
662 			}
663 		}
664 		rootPanel.add(panel, BorderLayout.CENTER);
665 
666 		if (logger.isLoggable(Level.CONFIG)) {
667 			logger.config("end"); //$NON-NLS-1$
668 		}
669 		return rootPanel;
670 	}
671 
672 
673 	public PdfPCell getReportForLearnerPDF(AnnotationService annotationService) {
674 		if (logger.isLoggable(Level.CONFIG)) {
675 			logger.config("start"); //$NON-NLS-1$
676 		}
677 
678 		int defaultFont = Font.TIMES_ROMAN;
679 		PdfPTable table = PDFUtil.createStepTitle(this.getTitle()); 
680 		PdfPTable questionAnswerTable = new PdfPTable(1);
681 
682 		List<ResponseDeclaration> reponseDeclarations = assessmentItem
683 				.getResponseDeclarations();
684 
685 		if (reponseDeclarations.isEmpty()) {
686 			PdfPCell noNoteTaken = new PdfPCell(new Paragraph(Messages
687 					.getString("Note.NOTE_NOT_TAKEN"))); //$NON-NLS-1$
688 			//table.addCell(noNoteTaken);
689 		} else {
690 			PdfPCell questionAnswerTableCell = null;
691 			Font font = new Font(defaultFont, 14, Font.NORMAL);
692 			font.setColor(PasColors.showAllWorkTextColor);
693 			
694 			ResponseDeclaration lastRd = null;
695 			for (ResponseDeclaration rd : reponseDeclarations) {
696 				BlockInteraction bi = Assessment
697 						.getInteractionByResponseDeclaration(
698 								getAssessmentItem().getItemBody()
699 										.getInteractions(), rd);
700 				String prompt = null;
701 				String answer = null;
702 
703 				if (bi == null) {
704 					prompt = null;
705 				} else {
706 					prompt = bi.getPrompt();
707 				}// if
708 
709 				PdfPCell noteQuestionCell = null;
710 				if (prompt == null) {
711 					prompt = Messages.getString("Note.ERROR_PROMPT_NOT_FOUND"); //$NON-NLS-1$
712 
713 					noteQuestionCell = new PdfPCell(new Paragraph(prompt, font));
714 					noteQuestionCell.setBorderWidthBottom(0.0f);
715 					noteQuestionCell.setGrayFill(0.8f);
716 				} else {
717 					//					
718 					StringReader stringReader = new StringReader(prompt);
719 					List<Element> p = null;
720 					try {
721 						StyleSheet st = new StyleSheet();
722 						st.loadTagStyle("body", "face", "Times New Roman");
723 						// st.loadTagStyle("body", "encoding", "Identity-H");
724 						st.loadTagStyle("body", "font-size", "6,0");
725 
726 						p = HTMLWorker.parseToList(stringReader, st);
727 
728 					} catch (IOException e) {
729 						e.printStackTrace();
730 					}// try
731 
732 					stringReader.close();
733 
734 					noteQuestionCell = new PdfPCell();
735 					for (Element e : p) {
736 						noteQuestionCell.addElement(e);
737 					}
738 
739 					noteQuestionCell.setBorderWidthBottom(0.0f);
740 					noteQuestionCell.setGrayFill(0.8f);
741 				}
742 
743 			
744 
745 				if (bi == null) {
746 					answer = null;
747 				} else {
748 					answer = lastAnswer(this.getResponseDeclarationToSocks(),
749 							rd);
750 				}// if
751 
752 				if (answer == null) {
753 					answer = Messages.getString("Note.NOT_ANSWERED"); //$NON-NLS-1$					
754 				} else if (bi instanceof ChoiceInteraction) {
755 					ChoiceInteraction<String> ci = (ChoiceInteraction<String>) bi;
756 
757 					List<SimpleChoice<String>> simpleChoices = ci.getSimpleChoices();
758 					for (SimpleChoice<String> choice : simpleChoices) {
759 						if (choice.getIdentifier().equals(answer)) {
760 							answer = choice.getContent();
761 						}
762 					}
763 				}
764 
765 				PdfPCell noteAnswerCell = new PdfPCell(new Paragraph(answer,
766 						font));
767 				noteAnswerCell.setBorderWidthTop(0.0f);
768 
769 				
770 				
771 				questionAnswerTable.addCell(noteQuestionCell);
772 				questionAnswerTable.addCell(noteAnswerCell);
773 			
774 
775 				questionAnswerTableCell = new PdfPCell(questionAnswerTable);
776 				questionAnswerTableCell.setPaddingLeft(9.0f);
777 				questionAnswerTableCell.setBorderWidth(0.0f);
778 				lastRd = rd;
779 			}// for
780 			table.addCell(questionAnswerTableCell);
781 			
782 			if( annotationService != null && annotationService.isAvailable() == true ) {
783 				Font commentFontHeading = new Font(defaultFont, 10, Font.BOLD);
784 				Font commentFontText = new Font(defaultFont, 10, Font.ITALIC);
785 				
786 				
787 				PdfPCell headerCommentCell = new PdfPCell(new Paragraph("Comments & Score",
788 						commentFontHeading));
789 				headerCommentCell.setBorderWidthTop(0.0f);
790 				headerCommentCell.setPaddingLeft(9.0f);
791 				headerCommentCell.setBorderWidth(0.0f);
792 				
793 				String processTheAnnotations = AnnotationUtils.processTheAnnotations(this,sessionService, agentService, annotationService);
794 				
795 				String comments = null;
796 				if( processTheAnnotations != null && processTheAnnotations != AnnotationUtils.TEACHER_HAS_NOT_COMMENTED_YET ) {
797 					comments = processTheAnnotations;
798 				} else {
799 					comments = AnnotationUtils.TEACHER_HAS_NOT_COMMENTED_YET;
800 				}
801 				
802 			
803 				PdfPCell noteCommentCell = new PdfPCell(new Paragraph(comments,
804 						commentFontText));
805 				noteCommentCell.setBorderWidthTop(0.0f);
806 				noteCommentCell.setPaddingLeft(9.0f);
807 				noteCommentCell.setBorderWidth(0.0f);
808 				
809 				String processScore = AnnotationUtils.processScore(this, sessionService, agentService, annotationService);
810 				
811 				String score = null;
812 				if( processScore != null && processScore != AnnotationUtils.UNSCORED ) {
813 					score = processScore + " of " + this.getPossibleScore();
814 					
815 				} else {
816 					score = AnnotationUtils.UNSCORED;
817 				}
818 				PdfPCell noteScoreCell = new PdfPCell(new Paragraph(score,
819 						commentFontText));
820 				noteScoreCell.setBorderWidthTop(0.0f);
821 				noteScoreCell.setPaddingLeft(9.0f);
822 				noteScoreCell.setBorderWidth(0.0f);
823 				
824 				table.addCell(headerCommentCell);
825 				table.addCell(noteCommentCell);
826 				table.addCell(noteScoreCell);
827 				
828 //				Graphic
829 //				  Graphic horizontalLine = new Graphic();
830 //	              horizontalLine.setHorizontalLine(1f, 100f);
831 //	              PdfPCell hrCell = new PdfPCell(new Phrase (" "));
832 //	              hrCell.setColspan(5);
833 //	              hrCell.setBorder(PdfPCell.NO_BORDER);
834 //	              hrCell.addElement(horizontalLine);
835 //	              table.addCell( hrCell );
836 			}
837 			
838 		}
839 		PdfPCell mainCell = new PdfPCell(table);
840 		mainCell.setBorder(0);
841 
842 		if (logger.isLoggable(Level.CONFIG)) {
843 			logger.config("end"); //$NON-NLS-1$
844 		}
845 		
846 		return mainCell;
847 	}
848 
849 	/***
850 	 * Assessment needs to navigate back to its step with an part of its component has been clicked on
851 	 * 
852 	 * @param NavigateAction - the ability to go to a step
853 	 * 
854 	 */
855 	public JPanel getReportForLearnerWithAnnotations(
856 			final NavigateAction navigateAction) {
857 		if (logger.isLoggable(Level.CONFIG)) {
858 			logger.config("start"); //$NON-NLS-1$
859 		}
860 		JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
861 		rootPanel.setBackground(Color.GREEN);
862 
863 		JPanel panel = new JPanel();
864 		//panel.setBackground(Color.yellow);
865 		MigLayout m1 = new MigLayout("wrap 1");
866 		//panel.setOpaque(false);
867 		panel.setLayout(m1);
868 		//panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
869 
870 		List<ResponseDeclaration> responseDeclarations = assessmentItem
871 				.getResponseDeclarations();
872 
873 		if (responseDeclarations.isEmpty()) {
874 			JPanel itemPanel = new JPanel();
875 			itemPanel.setLayout(new BorderLayout(0, 0));
876 			//itemPanel.setOpaque(false);
877 			JLabel noNoteTakenLabel = createNoNoteTakenLabel();
878 			itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
879 			System.out.println("RD IS NOT LOADED");
880 			panel.add(itemPanel);
881 		} else {
882 			int iterator = 1;
883 			String oldPrompt="",prompt = "";
884 			
885 			for (ResponseDeclaration rd : responseDeclarations) {
886 				BlockInteraction bi = getInteractionByResponseDeclaration(rd);
887 				oldPrompt = bi.getPrompt();				
888 				int index = oldPrompt.indexOf("Part");
889 				int index2 = oldPrompt.indexOf("Partner");
890 
891 				
892 				iterator++;
893 				JComponent htmlPromptPanel = AssessmentUI.createPromptPanel(bi);
894 				
895 				htmlPromptPanel.addMouseListener(new MouseListener(){
896 
897 					public void mouseClicked(MouseEvent e) {
898 						navigateAction.actionPerformed(null);
899 						
900 					}
901 
902 					public void mouseEntered(MouseEvent e) {
903 						// TODO Auto-generated method stub
904 						
905 					}
906 
907 					public void mouseExited(MouseEvent e) {
908 						// TODO Auto-generated method stub
909 						
910 					}
911 
912 					public void mousePressed(MouseEvent e) {
913 						// TODO Auto-generated method stub
914 						
915 					}
916 
917 					public void mouseReleased(MouseEvent e) {
918 						// TODO Auto-generated method stub
919 						
920 					}});
921 				
922 				bi.setPrompt(oldPrompt);
923 				JPanel questionAnswerPanel = new JPanel();
924 				questionAnswerPanel.setLayout(new BorderLayout(0, 0));
925 
926 				String answer = getAnswer(rd,bi);
927 				
928 				JPanel answerArea = createAnswerAreaWithAnnotations(htmlPromptPanel, answer, navigateAction);
929 				
930 				htmlPromptPanel.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
931 				
932 				questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
933 				questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
934 				
935 				setCurrentStepPart(questionAnswerPanel);
936 			//	setCurrentPrompt(bi.getPrompt());
937 			//	setCurrentAnswer(answerArea);
938 				panel.add(questionAnswerPanel);
939 				CompoundBorder compoundBorder = createCompoundBorder();
940 				panel.setBorder(compoundBorder);
941 				//panel.setOpaque(false);
942 
943 			}
944 		}
945 		rootPanel.add(panel, BorderLayout.CENTER);
946 		
947 		if (logger.isLoggable(Level.CONFIG)) {
948 			logger.config("end"); //$NON-NLS-1$
949 		}
950 
951 		return rootPanel;
952 	}
953 	
954 	/***
955 	 * Note used any more
956 	 */
957 	public JPanel getReportForLearnerWithAnnotations() {
958 		if (logger.isLoggable(Level.CONFIG)) {
959 			logger.config("start"); //$NON-NLS-1$
960 		}
961 		JPanel rootPanel = new JPanel(new BorderLayout(0, 0));
962 		rootPanel.setBackground(Color.GREEN);
963 
964 		JPanel panel = new JPanel();
965 		//panel.setBackground(Color.yellow);
966 		MigLayout m1 = new MigLayout("wrap 1");
967 		//panel.setOpaque(false);
968 		panel.setLayout(m1);
969 		//panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
970 
971 		List<ResponseDeclaration> responseDeclarations = assessmentItem
972 				.getResponseDeclarations();
973 
974 		if (responseDeclarations.isEmpty()) {
975 			JPanel itemPanel = new JPanel();
976 			itemPanel.setLayout(new BorderLayout(0, 0));
977 			//itemPanel.setOpaque(false);
978 			JLabel noNoteTakenLabel = createNoNoteTakenLabel();
979 			itemPanel.add(noNoteTakenLabel, BorderLayout.WEST);
980 			System.out.println("RD IS NOT LOADED");
981 			panel.add(itemPanel);
982 		} else {
983 			int iterator = 1;
984 			String oldPrompt="",prompt = "";
985 			
986 			for (ResponseDeclaration rd : responseDeclarations) {
987 				BlockInteraction bi = getInteractionByResponseDeclaration(rd);
988 				oldPrompt = bi.getPrompt();				
989 				int index = oldPrompt.indexOf("Part");
990 				int index2 = oldPrompt.indexOf("Partner");
991 
992 				iterator++;
993 				JComponent htmlPromptPanel = AssessmentUI.createPromptPanel(bi);
994 				bi.setPrompt(oldPrompt);
995 				JPanel questionAnswerPanel = new JPanel();
996 				questionAnswerPanel.setLayout(new BorderLayout(0, 0));
997 
998 				String answer = getAnswer(rd,bi);
999 				
1000 				JPanel answerArea = createAnswerAreaWithAnnotations(htmlPromptPanel, answer, null);
1001 				
1002 				htmlPromptPanel.setBorder(BorderFactory.createMatteBorder(0,0,1,0,Color.BLACK));
1003 				
1004 				questionAnswerPanel.add(htmlPromptPanel, BorderLayout.NORTH);
1005 				questionAnswerPanel.add(answerArea, BorderLayout.CENTER);
1006 				
1007 				setCurrentStepPart(questionAnswerPanel);
1008 			//	setCurrentPrompt(bi.getPrompt());
1009 			//	setCurrentAnswer(answerArea);
1010 				panel.add(questionAnswerPanel);
1011 				CompoundBorder compoundBorder = createCompoundBorder();
1012 				panel.setBorder(compoundBorder);
1013 				//panel.setOpaque(false);
1014 
1015 			}
1016 		}
1017 		rootPanel.add(panel, BorderLayout.CENTER);
1018 		
1019 		if (logger.isLoggable(Level.CONFIG)) {
1020 			logger.config("end"); //$NON-NLS-1$
1021 		}
1022 
1023 		return rootPanel;
1024 	}
1025 	
1026 /*****************************************************************************************************************/	
1027 /**********************************  SETTERS AND GETTERS *********************************************************/	
1028 	/*
1029 	 * setBiPrompt
1030 	 * getAssessmentItem,setAssessmentItem
1031 	 * getComponent
1032 	 * getResponses
1033 	 * getStudentAnswer
1034 	 * getInteractionByResponseDeclaration
1035 	 * setCurrentStepPart, getCurrentStepParts
1036 	 * setCurrentPrompt, getCurrentPrompts
1037 	 * setCurrentAnswer, getCurrentAnswers
1038 	 * getInteractionByResponseDeclaration
1039 	 */
1040 	
1041 
1042 	/***
1043 	 * @param responseDeclarations
1044 	 * @param iterator
1045 	 * @param filteredPrompt
1046 	 * @param bi
1047 	 */
1048 	private void setBiPrompt(List<ResponseDeclaration> responseDeclarations, int iterator, BlockInteraction bi) {
1049 		String oldPrompt = bi.getPrompt();
1050 		int index = oldPrompt.indexOf("Part");
1051 		int index2 = oldPrompt.indexOf("Partner");
1052 		String filteredPrompt = extractBody(oldPrompt);
1053 			
1054 		if(responseDeclarations.size() > 1){
1055 			if((index < 0) || (index==index2)){
1056 				bi.setPrompt("<html><body> Part " + iterator + " : " + filteredPrompt + "</body></html>");
1057 			}else{
1058 				bi.setPrompt("<html><body>" + filteredPrompt + "</body></html>");
1059 			}
1060 		}else{
1061 			bi.setPrompt("<html><body>" + filteredPrompt + "</body></html>");
1062 		}
1063 	}
1064 
1065 	public AssessmentItem getAssessmentItem() {
1066 		return assessmentItem;
1067 	}
1068 
1069 	public void setAssessmentItem(AssessmentItem assessmentItem) {
1070 		Object old = this.assessmentItem;
1071 		this.assessmentItem = assessmentItem;
1072 		firePropertyChange("assessmentItem", old, assessmentItem);
1073 	}
1074 
1075 	abstract public Component getComponent();
1076 
1077 	/***
1078 	 * @return the responses
1079 	 */
1080 	public Map<String, Object> getResponses() {
1081 		return responses;
1082 	}
1083 
1084 	/***
1085 	 * Given choiceInteraction, returns student's last choice, if any
1086 	 * 
1087 	 * @param interaction
1088 	 * @return String student's answer
1089 	 */
1090 	public static String getStudentAnswer(Assessment assessment,
1091 			BlockInteraction interaction) {
1092 		List<ResponseDeclaration> reponseDeclarations = assessment
1093 				.getAssessmentItem().getResponseDeclarations();
1094 		for (ResponseDeclaration rd : reponseDeclarations) {
1095 			if (rd.getIdentifier().equals(interaction.getResponseIdentifier())) {
1096 				String studentAnswer = Assessment.lastAnswer(assessment
1097 						.getResponseDeclarationToSocks(), rd);
1098 				return studentAnswer;
1099 			}
1100 		}
1101 		return null;
1102 	}
1103 	
1104 	
1105 	private void setCurrentStepPart(JPanel currentPart){
1106 		List<JPanel> currentStepParts = this.currentStepParts;
1107 		currentStepParts.add(currentPart);
1108 		this.currentStepParts = currentStepParts;
1109 	}
1110 	
1111 	public List<JPanel> getCurrentStepParts(){
1112 		return this.currentStepParts;
1113 	}
1114 	
1115 	private void setCurrentPrompt(String currentPrompt){
1116 		List<String> currentPrompts = this.currentPrompts;
1117 		currentPrompts.add(currentPrompt);
1118 		this.currentPrompts = currentPrompts;
1119 	}
1120 	
1121 	public List<String> getCurrentPrompts(){
1122 		return this.currentPrompts;
1123 	}
1124 	
1125 	private void setCurrentAnswer(JLabel answerArea){
1126 		List<JLabel> currentAnswers = this.answer;
1127 		currentAnswers.add(answerArea);
1128 		this.answer = currentAnswers;	
1129 	}
1130 	
1131 	public List<JLabel> getCurrentAnswers(){
1132 		return this.answer;
1133 	}
1134 	
1135 	/***
1136 	 * @return
1137 	 */
1138 	private CompoundBorder createCompoundBorder() {
1139 		CompoundBorder compoundBorder = BorderFactory
1140 				.createCompoundBorder(BorderFactory.createEmptyBorder(
1141 						0, 8, 0, 0), BorderFactory.createLineBorder(
1142 						PasColors.noteReportLineBorderColor, 1));
1143 		return compoundBorder;
1144 	}
1145 
1146 	private BlockInteraction getInteractionByResponseDeclaration(ResponseDeclaration rd){
1147 		return Assessment
1148 		.getInteractionByResponseDeclaration(
1149 				getAssessmentItem().getItemBody()
1150 						.getInteractions(), rd);
1151 	}
1152 
1153 	public static BlockInteraction getInteractionByResponseDeclaration(
1154 			List<BlockInteraction> interactions, ResponseDeclaration rd) {
1155 
1156 		for (BlockInteraction bi : interactions) {
1157 			if (bi.getResponseIdentifier().equals(rd.getIdentifier())) {
1158 				return bi;
1159 			}
1160 		}
1161 
1162 		return null;
1163 	}
1164 
1165 	abstract public String getType();
1166 	
1167 	/***
1168 	 * @return the responseDeclarationToSocks
1169 	 */
1170 	public Map<ResponseDeclaration, ISock<String>> getResponseDeclarationToSocks() {
1171 		return responseDeclarationToSocks;
1172 	}
1173 	
1174 	/***
1175 	 * @see org.telscenter.pas.beans.IWorkReporter#getEntityToPromptMap()
1176 	 */
1177 	public Map<String, String> getEntityToPromptMap() {
1178 		Map<String, String> rimToPromptMap = new HashMap<String, String>();
1179 		List<ResponseDeclaration> responseDeclarations = assessmentItem
1180 		    .getResponseDeclarations();
1181 		for (ResponseDeclaration responseDeclaration : responseDeclarations) {
1182 			String rimname = responseDeclaration.getRim().getName();
1183 			BlockInteraction bi = getInteractionByResponseDeclaration(responseDeclaration);
1184 			String prompt = bi.getPrompt();
1185 
1186 			rimToPromptMap.put(rimname, prompt);
1187 		}
1188 		return rimToPromptMap;
1189 	}
1190 
1191 	/***
1192 	 * @return the injectPrompt
1193 	 */
1194 	public boolean isInjectPrompt() {
1195 		return injectPrompt;
1196 	}
1197 
1198 	/***
1199 	 * @param injectPrompt the injectPrompt to set
1200 	 */
1201 	public void setInjectPrompt(boolean injectPrompt) {
1202 		this.injectPrompt = injectPrompt;
1203 	}
1204 
1205 	public Integer getPossibleScore() {
1206 		return possibleScore;
1207 	}
1208 
1209 	public void setPossibleScore(Integer possibleScore) {
1210 		this.possibleScore = possibleScore;
1211 	}
1212 
1213 	public boolean getTabbed() {
1214 		return isTabbed;
1215 	}
1216 
1217 	public void setTabbed(boolean isTabbed) {
1218 		this.isTabbed = isTabbed;
1219 	}
1220 
1221 	public AgentService getAgentService() {
1222 		return agentService;
1223 	}
1224 
1225 
1226 	public SessionService getSessionService() {
1227 		return sessionService;
1228 	}
1229 
1230 	public boolean isSubmitted() {
1231 		return this.submitted;
1232 	}
1233 
1234 	public void setSubmitted(boolean hasSubmitted) {
1235 		this.submitted = hasSubmitted;
1236 	} 
1237 
1238 }