/* 
 *  EmailForm.java
 * 
 *  Copyright 2018 Avaya Inc. All Rights Reserved.
 * 
 *  Usage of this source is bound to the terms described
 *  in AvayaLicenseSDK.rtf.
 * 
 *  Avaya - Confidential & Proprietary. Use pursuant to your signed agreement
 *  or Avaya Policy
 * 
 */
package com.avaya.ccs.javafxrefclient;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.avaya.ccs.api.CodeListI;
import com.avaya.ccs.api.ContactCenterCodeI;
import com.avaya.ccs.api.CustomerHistoryI;
import com.avaya.ccs.api.CustomerInteractionMediaItemI;
import com.avaya.ccs.api.DestinationI;
import com.avaya.ccs.api.DestinationListI;
import com.avaya.ccs.api.SuggestedResponseI;
import com.avaya.ccs.api.enums.InteractionType;
import com.avaya.ccs.core.*;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.web.HTMLEditor;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;

public class EmailForm implements MediaFormI{
	//AUDIT fields

	private TextArea reviewComment = new TextArea();
	private final Button rejectButton = new Button("Reject");
	private final Button approveButton = new Button("Approve");
	protected HBox hboxButtonRowApproval = new HBox(5);
	Scene reviewScene;
	Stage reviewStage;
	boolean isForApprovalAudit = false;
	List<Long> approvalIds = new ArrayList<>();
	//
	private final Stage emailForm = new Stage();
	private static final Logger LOG = Logger.getLogger(EmailForm.class);
	private final InteractionExecutor interactionExe;
	private Scene emailScene;
	private ScrollPane scrollPaneForTab1;
	private ScrollPane scrollPaneForTab2;
	
	private InteractionData interactionData;

	private TabPane tabPane;
	private Tab tab1;
	private Tab tab2;
	
	private EmailMedia emailMedia;
	private final String userId;
	private ConsultForm emailTransferForm; 
	private String agentSignature;
	private CodeList dispositionCodes;
	private CodeList activityCodes;
	private LocalDate rescheduleDate;
	private LocalDate followUpDate;
	
	private Label fromLabel= new Label("From"); //only used in email replies
	private Label toLabel= new Label("To"); //only used in ad-hoc email
	private TextField fromField=new TextField();
	private Label ccLabel= new Label("Cc");
	private TextField ccField = new TextField(); 
	private Label bccLabel= new Label("Bcc");
	private TextField bccField = new TextField();
	private Label subjectLabel = new Label("Subject");
	private TextField subjectField= new TextField();

	private Label suggestedRespLbl = new Label("Suggested Responses");
	private final ObservableList<SuggestedResponse> suggestedResponsesOL = FXCollections.observableArrayList();
	private ListView<SuggestedResponse> suggestedResponsesListView = new ListView<>();

	private Label originatorsLbl= new Label("Originator");
	private final ObservableList<DestinationI> originatorsOL=FXCollections.observableArrayList();
	private ChoiceBox<DestinationI> originatorsCB = new ChoiceBox<>();

	private Label closingReasonLbl=new Label("Closing Reason");
	private final ObservableList<ContactCenterCode> closingReasonsOl= FXCollections.observableArrayList();;
	protected final ChoiceBox<ContactCenterCode> closingReasonCBox = new ChoiceBox<>();
	
	private Label activityCodeLbl=new Label("Activity code");
	private ObservableList<ContactCenterCode> activityCodesOl= FXCollections.observableArrayList();
	private ChoiceBox<ContactCenterCode> activityCodesCBox = new ChoiceBox<>();
	private Button setActivityCodeBtn = new Button("Set");
	private HBox hboxActivityCode= new HBox(5);

	private Label agentNoteslbl =  new Label("Agent Notes");
	private TextArea agentNotesTa = new TextArea();
	private Label agentClosingNotesLbl= new Label("Agent Closing Notes");
	private TextArea agentClosingNotesTa = new TextArea();
	private Label bodyLabel = new Label("Body");
	private HTMLEditor htmlEd=new HTMLEditor();

	private Label attachmentsLabel= new Label("Attachments");
	private final ObservableList<File> outgoingEmailAttachments= FXCollections.observableArrayList();
	private ListView<InboundAttachment> incomingEmailAttachmentView= new ListView<InboundAttachment>();
	private ListView<File> outgoingEmailAttachmentView= new ListView<>();

	private Label customerHistoryLbl= new Label("Customer History");
	private final ObservableList<CustomerHistoryItem> customerHistory = FXCollections.observableArrayList();
	private ListView<CustomerHistoryItem> customerHistoryListView= new ListView<>();
	private TextArea customerHistoryMediaItemTA = new TextArea();
	
	private Button replyButton= new Button("Reply (All)");

	private Button transferButton = new Button("Transfer"); 
	private Button finishButton = new Button("Finish");

	private Button sendButton= new Button("Send...");
	private Button cancelButton = new Button("Cancel");
	private Button selectFilesButton= new Button("Select Files");
	private Button closeButton= new Button("Close");
	private Button followUpBtn= new Button("Follow Up");
	private boolean isAdhocEmail;

	private Label rescheduleLbl = new Label ("Reschedule");
	private DatePicker rescheduleDp = new DatePicker ();
	private TextField rescheduleTime = new TextField();
	private Button rescheduleSave= new Button("Reschedule");
	private TextField rescheduleNote = new TextField();

	protected VBox vboxEmailFormTab = new VBox(5);
	private VBox vboxMoreTab = new VBox(5);
	protected VBox vboxMainArea= new VBox(5);
	protected HBox hboxButtonRow1= new HBox(5);
	private HBox hboxButtonRow2= new HBox(5);
	private VBox vboxEndRow = new VBox(5);
	private HBox hBoxRescheduleButtons= new HBox(5);
	HBox suggestedResponsesHbox = new HBox(5);

	public EmailForm(InteractionExecutor interactionExe, String css, String userId, boolean isAdhocEmail) {
		String methodName="EmailForm";
		this.userId=userId;
		this.interactionExe=interactionExe;
		
		this.isAdhocEmail=isAdhocEmail; //'ad-hoc' email means agent-initiated email.
		
		tab1= new Tab("Basic Email");
		tab2= new Tab("More...");
		
		tabPane=new TabPane();
		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
		
		scrollPaneForTab1= new ScrollPane();
		scrollPaneForTab1.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
		scrollPaneForTab1.setHbarPolicy(ScrollBarPolicy.NEVER);
		scrollPaneForTab1.setContent(vboxEmailFormTab);
		scrollPaneForTab1.setFitToWidth(true);		
		
		hboxActivityCode.setPadding(new Insets(10));
		hboxActivityCode.getChildren().addAll(activityCodeLbl, activityCodesCBox, setActivityCodeBtn);
		
		vboxMoreTab.getChildren().add(hboxActivityCode);
		
		scrollPaneForTab2= new ScrollPane();
		scrollPaneForTab2.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
		scrollPaneForTab2.setHbarPolicy(ScrollBarPolicy.NEVER);
		scrollPaneForTab2.setContent(vboxMoreTab);
		scrollPaneForTab2.setFitToWidth(true);
		vboxMoreTab.setFillWidth(true);
				
		vboxEmailFormTab.setPadding(new Insets(10));
		vboxMoreTab.setPadding(new Insets(10));

		vboxMoreTab.getChildren().addAll();
		suggestedResponsesListView.setPrefHeight(80);
		suggestedResponsesHbox.getChildren().addAll(suggestedRespLbl, suggestedResponsesListView);
		
		tabPane.getTabs().addAll(tab1, tab2);
		tab1.setContent(scrollPaneForTab1);
		tab2.setContent(scrollPaneForTab2);
		emailScene = new Scene(tabPane, 800, 850);
		
		emailScene.getStylesheets().add(css);
		emailForm.setScene(emailScene);
		emailForm.setTitle("Email");

		fromField.setEditable(false);
		ccField.setEditable(false);
		bccField.setEditable(false);
		subjectField.setEditable(false);
		htmlEd.setPrefHeight(200);
		htmlEd.setDisable(true);
		agentNotesTa.setPrefRowCount(1);
		agentNotesTa.setDisable(true);
		agentClosingNotesTa.setPrefRowCount(1);

		rescheduleTime.setPromptText("hh:mm (24 hour clock)");
		rescheduleNote.setPromptText("Agent Note");
		selectFilesButton.setDisable(true);
		cancelButton.setDisable(true);
		sendButton.setDisable(true);
		closeButton.setDisable(true);
		setAgentClosingNotesVisible(false);

		incomingEmailAttachmentView.setPrefHeight(30);
		outgoingEmailAttachmentView.setPrefHeight(30);
		outgoingEmailAttachmentView.setItems(outgoingEmailAttachments);
		incomingEmailAttachmentView.setCellFactory(new Callback<ListView<InboundAttachment>, ListCell<InboundAttachment>>() {
			@Override
			public ListCell<InboundAttachment> call(ListView<InboundAttachment> param) {
				ListCell<InboundAttachment> cell = new ListCell<InboundAttachment>() {

					@Override
					protected void updateItem(InboundAttachment item, boolean empty) {
						super.updateItem(item, empty);
						if (item != null) {
							setText(item.getName());
						}
					}
				};
				return cell;
			}
		});

		suggestedResponsesListView.setPrefHeight(60);
		suggestedResponsesListView.setItems(suggestedResponsesOL);
		suggestedResponsesListView.setCellFactory(param -> new ListCell<SuggestedResponse>() {
			@Override
			protected void updateItem(SuggestedResponse item, boolean empty) {
				super.updateItem(item, empty);

				if (empty || item == null || item.getName() == null) {
					setText(null);
				} else {
					setText(item.getName());
				}
			}
		});


		originatorsCB.setPrefWidth(200); 
		originatorsCB.setItems(originatorsOL);
	

		customerHistoryListView.setItems(customerHistory);
		customerHistoryListView.setPrefSize(400, 250);
		
		customerHistoryMediaItemTA.setPrefSize(400, 400);
		customerHistoryMediaItemTA.setEditable(false);

		
		closingReasonCBox.setPrefWidth(200);
		closingReasonCBox.setItems(closingReasonsOl);
		
		activityCodesCBox.setPrefWidth(200);
		activityCodesCBox.setItems(activityCodesOl);
		
		vboxMainArea.setPadding(new Insets(10));
		
		
		if (isAdhocEmail) {
			vboxMainArea.getChildren().addAll(
					originatorsLbl, originatorsCB);
		}
		approveButton.setDisable(false);
		rejectButton.setDisable(false);
		reviewComment.setPromptText("Enter your comment");
		reviewComment.setPrefColumnCount(15);
		reviewComment.setMaxHeight(5);
		hboxButtonRowApproval.getChildren().addAll(approveButton, rejectButton);
		hboxButtonRowApproval.setPadding(new Insets(10));
		VBox reviewEmailVbox = new VBox(10);
		reviewEmailVbox.getChildren().addAll(new Label("Review Comment"),reviewComment,hboxButtonRowApproval);
		reviewEmailVbox.setPadding(new Insets(10));
		reviewScene = new Scene(reviewEmailVbox);
		reviewStage = new Stage();
		reviewStage.setScene(reviewScene);
		reviewStage.setTitle("Approval Form");
		vboxMainArea.getChildren().add(isAdhocEmail ?  toLabel : fromLabel);
		vboxMainArea.getChildren().addAll(
				fromField,
				ccLabel, ccField,
				bccLabel, bccField, 
				subjectLabel, subjectField, 
				attachmentsLabel, incomingEmailAttachmentView, outgoingEmailAttachmentView, 
				bodyLabel,htmlEd,
				suggestedResponsesHbox,
				agentNoteslbl, agentNotesTa  
				);
		
		vboxMoreTab.getChildren().addAll(customerHistoryLbl, customerHistoryListView, customerHistoryMediaItemTA);
		hboxButtonRow1.getChildren().addAll(replyButton, transferButton, finishButton);
		hboxButtonRow1.setPadding(new Insets(10));
		hboxButtonRow2.setPadding(new Insets(10));
		hboxButtonRow2.getChildren().addAll(sendButton,cancelButton,closeButton, 
//				selectFilesButton, 
//				followUpBtn, //TODO add in a future release @conroy1
				closingReasonLbl, closingReasonCBox);
		hBoxRescheduleButtons.getChildren().addAll(rescheduleDp, rescheduleTime, rescheduleNote,rescheduleSave);
		vboxEndRow.getChildren().addAll(agentClosingNotesLbl, agentClosingNotesTa); //TODO add hBoxRescheduleButtons and rescheduleLbl in a future release @conroy1
		
		if (isAdhocEmail) {
			vboxEmailFormTab.getChildren().addAll(vboxMainArea, hboxButtonRow2,hBoxRescheduleButtons, vboxEndRow);
			disableControls(new Control[] {selectFilesButton,  
					followUpBtn, rescheduleDp, rescheduleTime, rescheduleSave, htmlEd, agentNotesTa});
			enableControls(new Control[] {ccField, bccField, htmlEd, sendButton, cancelButton, closeButton});
			fromField.setEditable(true);
			ccField.setEditable(true);
			bccField.setEditable(true);
			subjectField.setEditable(true);		
		} else {
			vboxEmailFormTab.getChildren().addAll(vboxMainArea, hboxButtonRow1, hboxButtonRow2, hBoxRescheduleButtons, vboxEndRow);
			disableControls(new Control[] {sendButton,cancelButton,selectFilesButton, closeButton, 
					followUpBtn, rescheduleDp, rescheduleTime, rescheduleSave, htmlEd, agentNotesTa});
		}

		emailTransferForm= new ConsultForm(interactionExe, css, InteractionType.EmailInteraction);
		
		htmlEd.addEventHandler(KeyEvent.KEY_PRESSED, event -> { //workaround to stop scrolling the scrollbar
			if(event.getCode() == KeyCode.SPACE) { event.consume(); } 
		}); 


		replyButton.setOnAction((ActionEvent t) ->{
			LOG.info("replyButton() ID:"+ emailMedia.getId());
			enableControls(new Control[] {sendButton,closeButton, selectFilesButton, cancelButton, htmlEd, agentNotesTa});
			disableControls(new Control[] {replyButton, transferButton, finishButton});
			fromField.setEditable(true);
			ccField.setEditable(true);
			bccField.setEditable(true);
			subjectField.setEditable(true);

			updateForm();

			String originalText = htmlEd.getHtmlText() ; 
			StringBuilder replyPreamble=new StringBuilder();
			replyPreamble.append("<br/>-----------------------------<br/>");
			replyPreamble.append("From: " + emailMedia.getFrom() + "<br/>");
			replyPreamble.append("Sent: " + emailMedia.getArrivalTime() + "<br/>");
			replyPreamble.append("To: "+ emailMedia.getTo() + "<br/>");
			replyPreamble.append("Subject: "+ emailMedia.getSubject() + "<br/><br/><br/>");
			
			htmlEd.setHtmlText(replyPreamble + originalText);
			htmlEd.setFocusTraversable(false);
		});


		transferButton.setOnAction((ActionEvent t) ->{ 
			LOG.info("transferButton() ID:"+ emailMedia.getId());
			emailTransferForm.initializeTransferForm(interactionData);
			emailTransferForm.setMediaForm(this);
			emailTransferForm.setAgentSignature(agentSignature);
			interactionExe.getConsultDestinations(interactionData.getId());
			emailTransferForm.show();
		});


		finishButton.setOnAction((ActionEvent t) -> {
			LOG.info("finishButton() ID:"+ emailMedia.getId());
			finishEmail(); //
			enableControls(new Control[] {closeButton, cancelButton, followUpBtn, rescheduleDp, rescheduleTime, rescheduleSave});
			disableControls(new Control[] {replyButton,  transferButton, finishButton, sendButton, selectFilesButton});	
		});


		sendButton.setOnAction((ActionEvent t) ->{
			LOG.info("sendButton() ID:"+ emailMedia.getId());
			sendReply();
			enableControls(new Control[] {closeButton, selectFilesButton, cancelButton});
			vboxMainArea.getChildren().removeAll(
					Arrays.asList(
//					skillsetsLbl, skillsetsListView, 
					fromLabel, fromField,
					ccLabel, ccField, bccField, bccLabel, subjectLabel,	subjectField,
					attachmentsLabel, incomingEmailAttachmentView, 	outgoingEmailAttachmentView,
					bodyLabel, htmlEd, agentNoteslbl, agentNotesTa
					));
			disableControls(new Control[] {sendButton, cancelButton, selectFilesButton});
			enableControls(new Control[] {followUpBtn, rescheduleDp, rescheduleTime, rescheduleSave});
		});


		cancelButton.setOnAction((ActionEvent t) ->{
			LOG.info("cancelButton() ID:"+ emailMedia.getId());
			enableControls(new Control[] {replyButton, transferButton, finishButton});
			updateForm();
			disableControls(new Control[] {sendButton, cancelButton, selectFilesButton, closeButton, htmlEd, agentNotesTa});
		});


		selectFilesButton.setOnAction((ActionEvent t) ->{
			LOG.info("selectFilesButton() ID:"+ emailMedia.getId());
			// load a filepicker
			FileChooser fileChooser = new FileChooser();
			fileChooser.setTitle("Open Resource File");
			File file = fileChooser.showOpenDialog(emailForm);
			if (file != null) {
				//when the filepicker is done, add the attachment to the InteractionMedia's list of files
				outgoingEmailAttachments.add(file);
				emailMedia.addNewAttachment(file);            	
			}
		});

		closeButton.setOnAction((ActionEvent t) -> {
			String id=emailMedia.getId();
			LOG.info("closeButton() ID:"+ id);
			String selectedCloseReasonCode = null;
			if (closingReasonCBox.getValue()!= null) {
				selectedCloseReasonCode = closingReasonCBox.getSelectionModel().getSelectedItem().getNumber();
			}

			if ( selectedCloseReasonCode != null){
				LOG.info("Disposition code used to tear down the interaction = " + selectedCloseReasonCode);
				interactionExe.end(id, selectedCloseReasonCode, agentClosingNotesTa.getText(), false);
			} else {
				LOG.info("No Disposition Code selected. Closing with no DC, no agent note.");
				interactionExe.end(id);
			}

			Stage s = (Stage)emailScene.getWindow();
			s.close();
		});


		followUpBtn.setOnAction((ActionEvent t) ->{   
			LOG.info("followUpBtn() ID:"+ emailMedia.getId());
			followUpDate = rescheduleDp.getValue();
			LOG.info(methodName, "followUp date clicked");
		});


		rescheduleDp.setOnAction((ActionEvent t) ->{    
			LOG.info("rescheduleDp() ID:"+ emailMedia.getId());
			rescheduleDate = rescheduleDp.getValue();
			LOG.info(methodName, "reschedule date selected: "+rescheduleDate);
		});


		rescheduleSave.setOnAction((ActionEvent t) -> {
			String id=emailMedia.getId();
			LOG.info("rescheduleSave() ID:"+ id);
			LOG.info("      TODO: send the request to the server with reschedule");
//			String date = "01/01/2019";
			String date = ""+rescheduleDate.getMonthValue()+"/"+rescheduleDate.getDayOfMonth()+"/"+rescheduleDate.getYear();
//			String time = "11:59";
			String time = rescheduleTime.getText();
			String agentNote = rescheduleNote.getText();
			interactionExe.rescheduleEmail(id, date, time, agentNote);
			//closeButton.fire();
		});
		
		setActivityCodeBtn.setOnAction((ActionEvent t) -> {
			interactionExe.setActivityCode(emailMedia.getId(), activityCodesCBox.getSelectionModel().getSelectedItem().getNumber());
			});
		approveButton.setOnAction((ActionEvent t) -> {
			if(reviewComment.getText().isEmpty()) {
				showAlert("Comment is mandatory");
			}else{
				for(Long approvalId: approvalIds) {
					interactionExe.reviewApprovedEmail(interactionData.getId(),approvalId, reviewComment.getText());
				}
				hboxButtonRowApproval.setDisable(true);
			}

		});
		rejectButton.setOnAction((ActionEvent t) -> {
			if(reviewComment.getText().isEmpty()) {
				showAlert("Comment is mandatory");
			}else {
				for (Long approvalId : approvalIds) {
					interactionExe.reviewRejectedEmail(interactionData.getId(), approvalId, reviewComment.getText());
				}
				hboxButtonRowApproval.setDisable(true);
			}
		});
		
		incomingEmailAttachmentView.setOnMouseClicked(new EventHandler<MouseEvent>() { //download attachments
			@Override
			public void handle(MouseEvent click) {
				LOG.info("incomingEmailAttachmentView().handle() ID:"+ emailMedia.getId());
				if (click.getClickCount() == 2) {
					//Use ListView's getSelected Item
					InboundAttachment attachment = (InboundAttachment)incomingEmailAttachmentView.getSelectionModel().getSelectedItem();
					//open file chooser
					FileChooser fileChooser = new FileChooser();
					fileChooser.setTitle("Save Attachment");
					fileChooser.setInitialFileName(attachment.getName());

					File file = fileChooser.showSaveDialog(emailForm);
					if (file != null) {
						try {
							URL loc = new URL(attachment.getAddress());
							try (InputStream in = loc.openStream()) {
								Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
							}

						} catch (IOException ex) {
							LOG.error("save attachment exception", ex);
						}
					}                 
				}
			}
		});

		suggestedResponsesListView.setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent click) {
				LOG.info("suggestedResponsesListView().handle() ID:"+ emailMedia.getId());
				if (click.getClickCount() == 2) {
					SuggestedResponseI response = suggestedResponsesListView.getSelectionModel().getSelectedItem();
					String existingEmailContents = htmlEd.getHtmlText();
					htmlEd.setHtmlText(response.getBody() + "<br/>" + existingEmailContents);
					subjectField.setText(response.getSubject());
					incomingEmailAttachmentView.getItems().addAll(response.getAttachments());
					replyButton.fire();
				}
			}
		});
		
		
		customerHistoryListView.setOnMouseClicked(new EventHandler<MouseEvent>() { //download attachments
			@Override
			public void handle(MouseEvent click) {
				if (click.getClickCount() == 2) {
					String contactId = customerHistoryListView.getSelectionModel().getSelectedItem().getContactId();
					interactionExe.getCustomerInteractionMedia(emailMedia.getId(), contactId);                
				}
			}
		});


	}
	private void showAlert(String comment) {
		Alert alert = new Alert(Alert.AlertType.ERROR);
		alert.setTitle("Error");
		alert.setHeaderText(null);
		alert.setContentText(comment);
		alert.showAndWait();
	}
	public void show() {
		LOG.debug("show()");
		emailForm.show();
	}

	public void setCustomerHistory(CustomerHistoryI custHistory){
		LOG.info("setCustomerHistory");
		custHistory.getCustomerInteractions().forEach(item ->customerHistory.add((CustomerHistoryItem) item));	
	}

	public void setIsForAudit(ApprovalInformation info) {
		this.isForApprovalAudit = (info.getApprovalCheck() == 1) && info.getApprovalCheckSpecified();
		if(this.isForApprovalAudit) {
			interactionExe.editStartEmail(interactionData.getId(), info.getEmailApproveData().getActionId());
		}
	}

	public void addApprovalId(ApprovalAuditInformation info) {
		this.approvalIds.add(info.getApprovalId());
	}
	
	public void enableControls(Control[] controls) {
		for (Control c: controls) {
			c.setDisable(false);
		}
	}

	public void disableControls(Control[] controls) {
		for (Control c: controls) {
			c.setDisable(true);
		} 
	}

	public void updateForm() {
		LOG.debug("updateForm()");
		this.fromField.setText(emailMedia.getFrom()); //TODO add the other parties from getTo(); 
		this.ccField.setText(emailMedia.getCc());
		this.bccField.setText(emailMedia.getBcc());
		this.subjectField.setText(emailMedia.getSubject());
		if (emailMedia.getEncoding().equals("PLAIN")) {
			//this is a Plain text email but our window is a html-viewer: so change newlines to <br/> etc.
			htmlEd.setHtmlText(htmlifyLineEndings(emailMedia.getBody()));
		} else {
			htmlEd.setHtmlText(emailMedia.getBody());
		}
	

		for (InboundAttachment a: emailMedia.getInboundAttachments()) {
			incomingEmailAttachmentView.getItems().add(a);
		}


		if(this.isForApprovalAudit) {
			if(approvalIds != null &&  !approvalIds.isEmpty() ) {
				hboxButtonRowApproval.setDisable(false);
				reviewStage.show();
			}
		}else{
			approvalIds.clear();
		}

	}


	private String htmlifyLineEndings(String body) {
		String returnStr = body.replaceAll("(\r\n|\n)", "<br />");
		return returnStr;
	}


	private void sendReply() {
		String methodName = "sendReply() ";
		String bodyHtml = htmlEd.getHtmlText();
		String emailTranscript=null;
		emailTranscript = bodyHtml;
		LOG.debug(methodName + "email transcript: " + emailTranscript);
		boolean isHtml = true; //client is html-only 

		if (isAdhocEmail) {
			int skillsetId = Integer.parseInt(originatorsCB.getSelectionModel().getSelectedItem().getNumber());
			
			emailMedia.create(
					fromField.getText().trim(),
					ccField.getText().trim(),
					bccField.getText().trim(),
					subjectField.getText(),
					emailTranscript,
					agentNotesTa.getText(),
					true,
					skillsetId,
					isHtml);
		} else {
			emailMedia.reply(
					fromField.getText().trim(), 
					ccField.getText().trim(), 
					bccField.getText().trim(),
					subjectField.getText(), 
					emailTranscript,
					agentNotesTa.getText(), 
					true,
					isHtml
					);
		}
		setAgentClosingNotesVisible(true); 
	}

	private void finishEmail() {
		LOG.info("finishEmail()");
		setAgentClosingNotesVisible(true); 
	}

	@Override
	public void close() {
		LOG.info("closeEmail()");
		Stage s = (Stage)emailScene.getWindow();
		s.close();
	}

	private void setAgentClosingNotesVisible(boolean val) {
		LOG.info("setAgentClosingNotesVisible()");
		agentClosingNotesLbl.setVisible(val);
		agentClosingNotesTa.setVisible(val);
	}

	public void setInteractionMedia(EmailMedia imedia) {
		LOG.debug("setInteractionMedia()");
		this.emailMedia=imedia;

		//when the media object is set, we can request suggested responses and customer history
		if (isAdhocEmail) {
			//request the skillsets. The Originator/From field in ad-hoc email is populated by skillsets
			interactionExe.getSkillsets(emailMedia.getId());
		}

		imedia.requestSuggestedResponses();
		if (!isAdhocEmail) {
			interactionExe.getCustomerHistory(interactionData.getId());
		}
		interactionExe.getDispositionCodes(this.emailMedia.getId());
		interactionExe.getActivityCodes(this.emailMedia.getId());
		interactionExe.getApprovalStatus(interactionData.getId());
		//update the fields
		updateForm();
	}

	public void setDispositionCodes(CodeListI codes) {
		LOG.debug("setDispositionCodes()");
		this.dispositionCodes=(CodeList) codes;
		for (ContactCenterCodeI item: dispositionCodes.getCodes()) {
			ContactCenterCode thisItem = (ContactCenterCode) item;
			if (!closingReasonsOl.contains(thisItem))
				closingReasonsOl.add(thisItem);
		}		 
	}
	
	public void setSuggestedResponses(SuggestedResponses suggestedResponses) {
		LOG.debug("setSuggestedResponses()");
		Arrays.asList(suggestedResponses.getSuggestedResponses()).forEach(item ->{
			suggestedResponsesOL.add((SuggestedResponse) item);
		});
	}
	
	
	public void setOriginators(DestinationListI skillsets) { //
		LOG.debug("setOriginators()");
		for (DestinationI skillset: skillsets.getDestinations()) {
			originatorsOL.add(skillset);
		}
	}
	
	public void setActivityCodes(CodeListI codes) {
		LOG.debug("setActivityCodes()");
		this.activityCodes=(CodeList) codes;
		for (ContactCenterCodeI item: activityCodes.getCodes()) {
			ContactCenterCode thisItem = (ContactCenterCode) item;
			if (!activityCodesOl.contains(thisItem))
				activityCodesOl.add(thisItem);
		}		 
	}


	public void setInteractionData(InteractionData interactionData) {
		LOG.debug("setInteractionData()");
		this.interactionData=interactionData;
		emailTransferForm.setInteractionMedia(emailMedia);
		//once the interactionData is set, we can populate the ConsultForm
		emailTransferForm.initializeTransferForm(interactionData);
		emailTransferForm.setCurrentInteractionId(interactionData.getId());
	}

	public void setAgentSignature(String signature) {
		this.agentSignature=signature;
	}

	public TextField getFromField() {
		return fromField;
	}

	public String getBodyHtml() {
		return htmlEd.getHtmlText();
	}

	public TextField getSubjectField() {
		return subjectField;
	}

	public ConsultForm getConsultForm()	{
		return emailTransferForm;
	}

	public void setCustomerInteractionMediaList(CustomerInteractionMediaList value) {
		List<CustomerInteractionMediaItem> items = value.getCustomerInteractionMediaItems();
		StringBuilder mediaSB = new StringBuilder();
		
		for (CustomerInteractionMediaItemI item:items) {
			mediaSB.append(item.toString()+"\n");
		}		
		customerHistoryMediaItemTA.setText(mediaSB.toString());
	}
}