package com.avaya.ccs.javafxrefclient;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;

import com.avaya.ccs.api.AutoPhrasesI;
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.PagePushUrlListI;
import com.avaya.ccs.api.enums.InteractionState;
import com.avaya.ccs.api.enums.InteractionType;
import com.avaya.ccs.api.enums.StateReason;
import com.avaya.ccs.api.enums.WebChatMethod;
import com.avaya.ccs.core.CodeList;
import com.avaya.ccs.core.ContactCenterCode;
import com.avaya.ccs.core.CustomerHistoryItem;
import com.avaya.ccs.core.CustomerInteractionMediaItem;
import com.avaya.ccs.core.CustomerInteractionMediaList;
import com.avaya.ccs.core.ScreenPop;
import com.avaya.ccs.core.TranscriptMessage;
import com.avaya.ccs.core.WebChatMedia;

import javafx.application.Platform;
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.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Separator;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TabPane.TabClosingPolicy;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebchatForm implements MediaFormI{

	private final Stage stage = new Stage();
    private static final Logger LOG = Logger.getLogger(WebchatForm.class);
    private final InteractionExecutor interactionExe;
    
    private Scene webChatScene;
    private ScrollPane scrollPaneTab1;
    private ScrollPane scrollPaneTab2;
    
    private ConsultForm consultTransferForm;
    
    
	final Separator separator = new Separator();
	
	private TabPane tabPane;
	private Tab tab1;
	private Tab tab2;
    
    String interactionId;
     
    String agentLabel="";
    String customerLabel="";
    String consultedAgentLabel="";
    String skillset;
        
    Label contactIdLbl;
    Label skillsetLbl;

    Label customerIsTypingLbl = new Label("");
    Label thirdPartyIsTypingLbl = new Label("");
    CheckBox sendTranscriptCB = new CheckBox("Email Transcript");
    
    TextArea transcriptTa;  
    TextField inputMessageTf;
    
    //whisper/consult
    TextArea whisperTranscriptTa;  
    TextField whisperInputMessageTf;
    Button sendWhisperBtn;
    
    Button sendBtn;
    Button transferBtn;
    
    //closing
    Label closingReasonLbl=new Label("Closing Reason");
	ObservableList<ContactCenterCode> closingReasonsOl= FXCollections.observableArrayList();;
	ChoiceBox<ContactCenterCode> closingReasonCBox = new ChoiceBox<>();
	Button cancelBtn;
    Button closeBtn;
    TextArea closingAgentNoteTa;
    
    
    ObservableList<ContactCenterCode> activityCodesOl= FXCollections.observableArrayList();;
	ChoiceBox<ContactCenterCode> activityCodesCBox = new ChoiceBox<>();
	Label activityCodesLbl=new Label("Activity Code");
	Button setActivityCodeBtn = new Button("Set");
	
    private Label ppushLbl;
    private Button ppushBtn;
    private ObservableList<String> ppushUrlsOl;
	private ChoiceBox<String> ppushUrlsCBox;
    
    private Label autoPhrasesLbl;
    private ChoiceBox<String> autoPhrasesCB;
    private ObservableList<String> autoPhrasesOl;
    private Button autoPhrasesBtn;
    
    CodeList dispositionCodes= new CodeList();
    
    private VBox mainContainerVBox = new VBox(5);
    private VBox tab2ContainerVBox = new VBox(5);
	
	InteractionData interactionData=null;
	
	WebChatMedia media;
	private String css;

	HBox completeConsultHbox;
	Button closeConsult;
	Button completeAsConference;
	Button completeAsTransfer;
	
	boolean isSupervised =false; //is this a Supervisor observing /barging a webchat
	private boolean isInteractionDataSet;
	private boolean agentIsTyping;
	private boolean customerIsTyping;
	private boolean thirdPartyIsTyping;
	
	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();
	
	
	public WebchatForm(String interactionId, InteractionExecutor interactionExe, String css) {
		LOG.info("WebchatForm constructor called. Id: "+ interactionId);
		
		this.interactionExe=interactionExe;
		this.css=css;
		this.interactionId=interactionId;
		
		tabPane=new TabPane();
		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
		tab1= new Tab("Basic Webchat");
		tab2= new Tab("More...");
		
		consultTransferForm= new ConsultForm(interactionExe, css, InteractionType.ChatInteraction);
		
		//initialise controls
	    contactIdLbl= new Label("");
	    
	    skillsetLbl= new Label("Skillset: ");
	    transcriptTa = new TextArea();
	    transcriptTa.setPrefRowCount(10);
	    transcriptTa.setEditable(false);
	    
	    whisperTranscriptTa= new TextArea();
	    whisperTranscriptTa.setPrefRowCount(6);
	    
	    inputMessageTf= new TextField();
	    inputMessageTf.setOnKeyPressed(new EventHandler<KeyEvent>(){
			@Override
	        public void handle(KeyEvent ke){
	            if (ke.getCode().equals(KeyCode.ENTER)) {
	                sendBtn.fire();
	            }
	            agentIsTyping=true;
	        }
	    });
	    
	    
	    whisperInputMessageTf= new TextField();
	    whisperInputMessageTf.setOnKeyPressed(new EventHandler<KeyEvent>(){
	        @Override
	        public void handle(KeyEvent ke)
	        {
	            if (ke.getCode().equals(KeyCode.ENTER)) {
	                sendWhisperBtn.fire();
	            }
	        }
	    });
	    
	    
	    sendBtn= new Button("Send");
	    transferBtn = new Button("Transfer");

	    HBox isTypingLabelsHBox =new HBox(5);
	    isTypingLabelsHBox.getChildren().addAll(customerIsTypingLbl, thirdPartyIsTypingLbl);
	    
	    HBox sendRowHbox= new HBox(5);
	    sendRowHbox.setPadding(new Insets(10));
	    sendRowHbox.getChildren().addAll(sendBtn, transferBtn);
	    
	    HBox closingRowHBox= new HBox(5);
	    closingRowHBox.setPadding(new Insets(10));
	    
	    closingReasonsOl= FXCollections.observableArrayList();;
		closingReasonCBox = new ChoiceBox<>();
		closingReasonCBox.setPrefWidth(200);
		closingReasonCBox.setItems(closingReasonsOl);
		
		activityCodesCBox.setPrefWidth(200);
		activityCodesCBox.setItems(activityCodesOl);
		
		HBox activityCodesHbox= new HBox(5);
		activityCodesHbox.setPadding(new Insets(10));
		activityCodesHbox.getChildren().addAll(activityCodesLbl, activityCodesCBox, setActivityCodeBtn);
				
		
		cancelBtn = new Button("Cancel");
	    closeBtn= new Button("Close");	  
	    closingAgentNoteTa= new TextArea();
	    Label closingAgentNoteLbl= new Label("Closing note:");
	    closingAgentNoteTa.setPrefRowCount(2);
	    
		closingRowHBox.getChildren().addAll(closeBtn, cancelBtn, closingReasonLbl, closingReasonCBox);
		
		mainContainerVBox.setPadding(new Insets(10));
		tab2ContainerVBox.setPadding(new Insets(10));
	    
	    Label consultLabel= new Label("Consult");
		sendWhisperBtn= new Button("Send Whisper");
		
		completeConsultHbox= new HBox(5);
		closeConsult = new Button("Close Consult");
		completeAsConference= new Button("Complete Conference");
		completeAsTransfer = new Button("Complete Transfer");
		completeConsultHbox.getChildren().addAll(closeConsult, completeAsConference, completeAsTransfer);
		
		HBox pagePushHbox = new HBox(5);
    	pagePushHbox.setPadding(new Insets(10));
    	
    	ppushLbl =new Label("Page push url:");
    	ppushUrlsOl= FXCollections.observableArrayList();
    	ppushUrlsCBox = new ChoiceBox<>();
    	ppushUrlsCBox.setPrefWidth(200);
    	ppushUrlsCBox.setItems(ppushUrlsOl);
    	
    	ppushBtn= new Button("Send");
    	pagePushHbox.getChildren().addAll(ppushLbl, ppushUrlsCBox, ppushBtn);
    	mainContainerVBox.getChildren().add(pagePushHbox);
    	
    	HBox autoPhrasesHbox = new HBox(5);
    	autoPhrasesHbox.setPadding(new Insets(10));
    	autoPhrasesLbl =new Label("Auto phrases:");
    	autoPhrasesOl= FXCollections.observableArrayList();
    	autoPhrasesCB = new ChoiceBox<>();
    	autoPhrasesCB.setPrefWidth(200);
    	autoPhrasesCB.setItems(autoPhrasesOl);
    	autoPhrasesBtn = new Button("Select");
    	autoPhrasesHbox.getChildren().addAll(autoPhrasesLbl, autoPhrasesCB, autoPhrasesBtn);
    	mainContainerVBox.getChildren().add(autoPhrasesHbox);
    	
    	customerHistoryListView.setItems(customerHistory);
		customerHistoryListView.setPrefHeight(250);
		
		customerHistoryMediaItemTA.setPrefSize(400, 400);
		customerHistoryMediaItemTA.setEditable(false);
	
	    //button action handlers
	    sendBtn.setOnAction((ActionEvent t) ->{ 
	    	String message=inputMessageTf.getText();
	    	interactionExe.sendWebChatMessage(media.getId(), message, false);
	    	transcriptTa.setText(transcriptTa.getText() + "\n"+ agentLabel+ ": "+ message);
	    	inputMessageTf.setText("");
        });
	    
	    ppushBtn.setOnAction((ActionEvent t) ->{ 
	    	String url=ppushUrlsCBox.getSelectionModel().getSelectedItem();
	    	if (url!="") {
	    		interactionExe.sendWebChatPagePush(media.getId(), url);
	    	}	    	
	    	transcriptTa.setText(transcriptTa.getText() + "\n"+ agentLabel+ ": [Page push URL:"+ url + "]");
	    	ppushUrlsCBox.getSelectionModel().clearSelection();
        });
	    
	    autoPhrasesBtn.setOnAction((ActionEvent t) ->{
	    	String phrase=autoPhrasesCB.getSelectionModel().getSelectedItem();
	    	if (phrase!="") {
	    		inputMessageTf.setText(phrase);
	    	}	    	
        });
	    
	    setActivityCodeBtn.setOnAction((ActionEvent t) -> {
	    	interactionExe.setActivityCode(media.getId(), activityCodesCBox.getSelectionModel().getSelectedItem().getNumber());
		});
	    	    
	    closeBtn.setOnAction((ActionEvent t) ->{
	    	if (closingReasonCBox.getValue()!=null) {
	    		interactionExe.end(interactionId, closingReasonCBox.getValue().getNumber(), closingAgentNoteTa.getText(), sendTranscriptCB.isSelected());
			} else {
	    		interactionExe.end(interactionId);
	    	}
	    	Stage s = (Stage)webChatScene.getWindow();
        	s.close();
	    });
	    
	    customerHistoryListView.setOnMouseClicked(new EventHandler<MouseEvent>() { //download attachments
			@Override
			public void handle(MouseEvent click) {
				LOG.debug("customerHistoryListView().handle() ID:"+ media.getId());
				if (click.getClickCount() == 2) {
					String contactId = customerHistoryListView.getSelectionModel().getSelectedItem().getContactId();
					interactionExe.getCustomerInteractionMedia(media.getId(), contactId);                
				}
			}
		});
	    
	    
	    //transfer/consult/conference button
	    transferBtn.setOnAction((ActionEvent t) ->{ 
        	consultTransferForm.initializeConsultForm(interactionData);
        	consultTransferForm.setMediaForm(this);
        	consultTransferForm.setAgentSignature(""); //TODO conroy1

        	interactionExe.getConsultDestinations(interactionData.getId());
        	consultTransferForm.show();
        });
	    
	    
	    sendWhisperBtn.setOnAction((ActionEvent t) ->{ 
	    	String message=whisperInputMessageTf.getText();
	    	interactionExe.sendWebChatMessage(media.getId(), message, true);
	    	whisperTranscriptTa.setText(whisperTranscriptTa.getText() + "\n"+ agentLabel+ ": "+ message);
	    	whisperInputMessageTf.setText("");
        });
	    
	    
	    completeAsConference.setOnAction((ActionEvent t) ->{ 
	    	LOG.debug("completeAsConference click");
	    	interactionExe.completeConference(media.getId());
	    	
	    	
	    	//Since now it's a conference, modify the action of CloseBtn to close conference TODO conroy1 check this is strong enuf
	    	closeBtn.setOnAction((ActionEvent t1) ->{      	  
		    	interactionExe.endConference(media.getId());
		    	Stage s = (Stage)webChatScene.getWindow();
	        	s.close();
		    });
	    	
        });
	    
	    
	    completeAsTransfer.setOnAction((ActionEvent t) ->{ 
	    	LOG.debug("completeAsTransfer click");
	    	interactionExe.completeTransfer(media.getId());
        });
	    
	    closeConsult.setOnAction((ActionEvent t) ->{ 
	    
	    	interactionExe.endConsult(media.getId());
	    	disableControls(new Control[] {whisperInputMessageTf, whisperTranscriptTa, sendTranscriptCB, sendWhisperBtn, closeConsult, completeAsTransfer, completeAsConference});
		    
        });
	    
	    
    	//add controls to teh main GUI container
	    mainContainerVBox.getChildren().addAll(contactIdLbl, skillsetLbl, transcriptTa,isTypingLabelsHBox, inputMessageTf, sendRowHbox, activityCodesHbox, closingRowHBox, closingAgentNoteLbl, closingAgentNoteTa, sendTranscriptCB, separator, consultLabel, whisperTranscriptTa, whisperInputMessageTf, sendWhisperBtn, completeConsultHbox);		
	    tab2ContainerVBox.getChildren().addAll(customerHistoryLbl, customerHistoryListView, customerHistoryMediaItemTA);
	    
	    // GUI elements layout
		scrollPaneTab1= new ScrollPane();
    	scrollPaneTab1.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
    	scrollPaneTab1.setHbarPolicy(ScrollBarPolicy.NEVER);
    	scrollPaneTab1.setContent(mainContainerVBox);
    	scrollPaneTab1.setFitToWidth(true);
		
    	scrollPaneTab2= new ScrollPane();
    	scrollPaneTab2.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
    	scrollPaneTab2.setHbarPolicy(ScrollBarPolicy.NEVER);
    	scrollPaneTab2.setContent(tab2ContainerVBox);
    	scrollPaneTab2.setFitToWidth(true);
    	
    	tabPane.getTabs().addAll(tab1, tab2);
		tab1.setContent(scrollPaneTab1);
		tab2.setContent(scrollPaneTab2);
 	
		webChatScene = new Scene(tabPane, 500, 550);
		webChatScene.getStylesheets().add(css);
        stage.setScene(webChatScene);
        stage.setTitle("Web Chat");

        disableControls(new Control[] {whisperInputMessageTf, whisperTranscriptTa, sendWhisperBtn, closeConsult, completeAsTransfer, completeAsConference});
              
        ScheduledExecutorService scheduler=Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(new IsTypingScheduledMonitor(), 3, 2, TimeUnit.SECONDS);
        
        LOG.info("WebchatForm constructor done");
	}
	
	public String getInteractionId() {
		return interactionId;
		}
	
	//called after the media member is set
	 public void updateForm() {
		 String methodName = "updateForm";
		 LOG.debug(methodName +  media.getMethod());
		 if (media.getMethod()!=null && media.getMethod().equals(WebChatMethod.newMessage)) {	 
			 if (media.getMessageType().equals("whisper")) {
				 String currentText=whisperTranscriptTa.getText();
				 this.whisperTranscriptTa.setText(currentText + "\n" + media.getDisplayName() + ": "+ media.getMessage());
			 } else {
				 String currentText=transcriptTa.getText();
				 this.transcriptTa.setText(currentText + "\n" + media.getDisplayName() + ": "+ media.getMessage());
			 }
		 }
	}
	
	private String transcriptToText(String[] messages) {
		StringBuilder transcriptBuilder= new StringBuilder();
		
		for (String message: Arrays.asList(messages))
			transcriptBuilder.append(message + "\n");
		
		return transcriptBuilder.toString();
	}

	public void show() {
    	LOG.debug("show()");
        stage.show();
    }
	

	public void setInteractionData(InteractionData interactionData) {
		LOG.debug("setInteractionData()");
		this.interactionData=interactionData;
		contactIdLbl.setText("Interaction ID: "+interactionId);
		consultTransferForm.setInteractionMedia(media);
		consultTransferForm.setCurrentInteractionId(interactionData.getId());
		updateInteractionData(interactionData);
		this.setInteractionDataSet(true);
	}
	
	public void setMedia(WebChatMedia media) {
    	LOG.debug("setMedia" +  " media isNull: "+(media==null));
    	if (media!=null)
    		this.media=media;
    	
    	//TODO conroy1 there is a timing issue on getting autophrases and ppurls. 
		// to resolve, don't send autophrase/ppurl requests until after the agentJoinRoom notification
    	try {Thread.sleep(500);} catch (InterruptedException e) {} 
    	
    	if (interactionData.canGetAutoPhrases())
    		interactionExe.getAutoPhrases(this.media.getId());
    	if (interactionData.canGetPagePushUrls())
    		interactionExe.getPagePushUrls(this.media.getId());
    	if (interactionData.canGetDispositionCodes())
    		interactionExe.getDispositionCodes(this.media.getId());
    	if (interactionData.canGetCustomerHistory())
    		interactionExe.getCustomerHistory(this.media.getId());
   		interactionExe.getActivityCodes(this.media.getId());
		interactionExe.getCustomFields(this.media.getId());
    	
		updateForm();
	}
	
	public void setCustomerHistory(CustomerHistoryI custHistory){
		LOG.info("setCustomerHistory");
		custHistory.getCustomerInteractions().forEach(item ->customerHistory.add(item));
	}

	public void setDispositionCodes(CodeListI codes) { 
		LOG.debug("setDispositionCodes");
		codes.getCodes().forEach( c -> this.dispositionCodes.addCodeToList(c));		
		codes.getCodes().forEach(c -> {
			if (!closingReasonsOl.contains(c))
				closingReasonsOl.add((ContactCenterCode) c);
			}	
		);	 
	}
	
	public void setActivityCodes(CodeListI codes) { 
		LOG.debug("setActivityCodes");
		codes.getCodes().forEach(c -> {
			if (!activityCodesOl.contains(c))
				activityCodesOl.add((ContactCenterCode) c);
			}	
		);	 
	}

	
	public void setPagePushUrls(PagePushUrlListI urlList) { 
		LOG.debug("setPagePushUrls");	
		urlList.getPagePushUrls().forEach(url -> {
			if (!ppushUrlsOl.contains(url.getUrl()))
				ppushUrlsOl.add(url.getUrl());
			}	
		);	 
	}

	
	public void setAutoPhrases(AutoPhrasesI phrases) { 
		LOG.debug("setAutoPhrases");	
		phrases.getAutoPhrases().forEach(phrase -> {
			if (!autoPhrasesOl.contains(phrase.getPhraseText()))
				autoPhrasesOl.add(phrase.getPhraseText());
			}	
		);	 
	}
	
	public void setCustomerLabelText(String text) {
		customerIsTypingLbl.setText(text);
	}
	
	public void setThirdPartyLabelText(String text) {
		thirdPartyIsTypingLbl.setText(text);
	}
	

	public void updateMedia(WebChatMedia media) {
		LOG.debug("updateMedia" + " media isNull: "+(media==null)); 
		
    	if (media.getAgentLabel()!=null) {
    		agentLabel=media.getAgentLabel(); 
    	}
    	
    	if (media.getCustomerLabel()!=null) {
    		customerLabel=media.getCustomerLabel();
    	}
    	
    	if (media.getMethod().equals(WebChatMethod.isTyping)) {
    		if (media.getSenderType().equals("customer"))
    			customerIsTyping = true;
    		else if (media.getSenderType().equals("agent"))
    			thirdPartyIsTyping = true;
    	} else if (media.getMethod().equals(WebChatMethod.agentJoinRoom)) {
    		if (media.getTranscript().getMessages().length>0) {
    			//is a consult or similar: write out the transcript
    			for (TranscriptMessage m: media.getTranscript().getMessages()) {
    				//achokoev - 10/31/2019 - CC-17948 - Workspaces doesn't display URLs in transcript
    				//Check, if the given message is a message or a pagePush
    				if (m.getType().equalsIgnoreCase("pagePush")){
    					transcriptTa.setText(transcriptTa.getText() + "\n"+ m.getDisplayName() + ": [Page push URL:"+ m.getUrl() + "]");
    				}
    				else {
    					transcriptTa.setText(transcriptTa.getText() + "\n"+ m.getDisplayName() + ": "+ m.getMessage());
    				}
    			}
    		}
    	} else if (media.getMethod().equals(WebChatMethod.pagePush)) {
    		transcriptTa.setText(transcriptTa.getText() + "\n"+ media.getDisplayName() + ": [Page push URL:"+ media.getUrl() + "]");
    	}
		this.media=media;
		updateForm();
	}
	
	public ConsultForm getConsultForm() {
    	return consultTransferForm;
    	}

	@Override
	public void close() {
		stage.close();
//		closeBtn.fire();
		Stage s = (Stage)webChatScene.getWindow();
    	s.close();	
	}

	@Override
	public 	void enableControls(Control[] controls) {
		LOG.debug("enableControls");
		for (Control c: controls) {
			c.setDisable(false);
			c.setFocusTraversable(true);
		}
	}
	
	@Override
	public void disableControls(Control[] controls) {
		LOG.debug("disableControls");
    	for (Control c: controls) {
			c.setDisable(true);
			c.setFocusTraversable(false);
		} 
    }


	public void updateInteractionData(InteractionData data) {
		this.interactionData=data;
		LOG.info("updateInteractionData called ");
		if (!consultTransferForm.isMediaSet()) {
			consultTransferForm.setInteractionMedia(media);
		}
		
		
		if(data.getStateReason()==StateReason.Observe) {
			
			this.sendBtn.setDisable(true);
			this.inputMessageTf.setDisable(true);
			
			this.whisperInputMessageTf.setDisable(false);
			this.sendWhisperBtn.setDisable(false);
		
		} else if (data.getStateReason()==StateReason.ConsultInitiated){
			this.sendBtn.setDisable(true);
			this.inputMessageTf.setDisable(true);
			this.whisperInputMessageTf.setDisable(false);
			this.sendWhisperBtn.setDisable(false);
		} else {
			this.closeConsult.setDisable(!data.canEndConsult());
			this.sendWhisperBtn.setDisable(!data.canCompleteConference());		
			this.completeAsConference.setDisable(!data.canCompleteConference());
			this.completeAsTransfer.setDisable(!data.canCompleteTransfer());
			this.sendWhisperBtn.setDisable(!data.canEndConsult());
			this.closeBtn.setDisable(!data.canEnd());
			this.whisperInputMessageTf.setDisable(!data.isConsult()); 
			this.whisperTranscriptTa.setDisable(!data.isConsult());
		}
		
	}


	public boolean isInteractionDataSet() {
		return isInteractionDataSet;
	}


	public void setInteractionDataSet(boolean isInteractionDataSet) {
		this.isInteractionDataSet = isInteractionDataSet;
	}
	
	/**
	 * checks to see if the Agent or Customer isTyping flags have been triggered
	 * if the Agent flag is triggered, send a IsTyping request and reset the flag
	 * if the Customer flag is triggered, update the appropriate label in the gui and reset the flag
	 * @author conroy1
	 *
	 */
	class IsTypingScheduledMonitor implements Runnable{

		@Override
		public void run() {
			if (agentIsTyping) {
				interactionExe.sendAgentIsTypingMessage(interactionId);
				agentIsTyping=false;			
			}
			
			if (customerIsTyping){
				Platform.runLater(new Runnable() {
					@Override public void run() {
						setCustomerLabelText("Customer is typing...");
						}
					});
				customerIsTyping=false;
			} else {
				Platform.runLater(new Runnable() {
					@Override public void run() {
						setCustomerLabelText("");
						}
					});
			} 
			
			if (thirdPartyIsTyping) {
				Platform.runLater(new Runnable() {
				@Override public void run() {
					setThirdPartyLabelText("Third party agent is typing...");
					}
				});
			thirdPartyIsTyping=false;
		} else {
			Platform.runLater(new Runnable() {
				@Override public void run() {
					setThirdPartyLabelText("");
					}
				});
			} 
		}		
	}
	
	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());
	}

	public void goToWrapup() {
		LOG.debug("goToWrapup");
		this.transcriptTa.appendText("\nThe customer has left the chat.");
		disableControls(new Control[] {inputMessageTf, sendBtn, transferBtn});
	}
}
