package org.gcube.portlets.user.reportgenerator.client;


import java.util.List;

import org.gcube.portlets.d4sreporting.common.shared.Metadata;
import org.gcube.portlets.user.gcubewidgets.client.popup.GCubeDialog;
import org.gcube.portlets.user.reportgenerator.client.Presenter.CommonCommands;
import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter;
import org.gcube.portlets.user.reportgenerator.client.dialog.ImporterDialog;
import org.gcube.portlets.user.reportgenerator.client.dialog.PagePropertiesDialog;
import org.gcube.portlets.user.reportgenerator.client.model.ExportManifestationType;
import org.gcube.portlets.user.reportgenerator.client.model.TemplateModel;
import org.gcube.portlets.widgets.lighttree.client.ItemType;
import org.gcube.portlets.widgets.lighttree.client.event.PopupEvent;
import org.gcube.portlets.widgets.lighttree.client.event.PopupHandler;
import org.gcube.portlets.widgets.lighttree.client.load.WorkspaceLightTreeLoadPopup;

import com.extjs.gxt.ui.client.widget.MessageBox;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.CellPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.MenuItemSeparator;
import com.google.gwt.user.client.ui.RichTextArea;



/**
 * <code> Headerbar </code> class is the top bar component of the UI 
 *
 * @author Massimiliano Assante, ISTI-CNR - massimiliano.assante@isti.cnr.it
 */
public class Headerbar extends Composite{

	private static final String ADD_BIBLIO_ENTRY = "Add citation";
	private static final String VIEW_BIBLIO = "View Bibliography";
	private static final String MANAGE_BIBLIO = "Delete citation(s)";
	private static final String EXPORT_OPENXML = "Export to OpenXML (docx)";
	private static final String EXPORT_HTML = "Export to HTML";
	private static final String EXPORT_FIMES = "Export to FiMES XML";
	private static final String EXPORT_XML = "Export to XML";
	private static final String EXPORT_ENCRYPTED_REPORT = "Save an Encrypted Version to Desktop";

	private static final String VIEW_USER_COMMENTS = "View user comments";

	String location;

	private Presenter presenter; 

	/**
	 * the template Model
	 */
	private TemplateModel templateModel;

	/**
	 * mainLayout Panel
	 */
	private CellPanel mainLayout = new HorizontalPanel();


	//private MenuItem optionPDF;

	private MenuItem importModel;
	
	private MenuItem addBiblioEntry;
	
	private MenuItem viewBiblio;
		
	private MenuItem manageBiblio;

	private MenuItem optionHTML;

	private MenuItem optionDOCX;
	
	private MenuItem optionPDF;

	private MenuItem optionFimes;
	
	private MenuItem optionXML;
	
	private MenuItem optionEncryptedModel;

	private MenuItem viewMetadata;
	
	private MenuItem viewComments;

	private MenuItem discardSection;



	MenuBar menuBar = new MenuBar();

	MenuItem fileMenu;
	MenuItem viewMenu;
	MenuItem sectionsMenu;
	MenuItem biblioMenu;
	MenuItem exportMenu;
	MenuItemSeparator separator1;
	MenuItemSeparator separator2;
	MenuItemSeparator separator3;
	MenuItemSeparator separator4;

	/**
	 * Constructor
	 * @param c the controller instance for this UI component
	 */
	public Headerbar(Presenter c) {
		this.presenter = c;
		this.templateModel = presenter.getModel();

		menuBar.setAutoOpen(false);
		//	menuBar.setWidth("100px");
		menuBar.setAnimationEnabled(true);
		fileMenu = getFileMenu();
		menuBar.addItem(fileMenu);
		separator1 = menuBar.addSeparator();
		viewMenu = getViewMenu();
		menuBar.addItem(viewMenu);
		separator2 = menuBar.addSeparator();
		sectionsMenu = getSectionMenu();
		menuBar.addItem(sectionsMenu);
		separator3 = menuBar.addSeparator();
		biblioMenu = getBiblioMenu();
		menuBar.addItem(biblioMenu);
		separator4 = menuBar.addSeparator();
		exportMenu = getExportsMenu();
		menuBar.addItem(exportMenu);
		
		mainLayout.setSize("100%", "24px");
		mainLayout.setStyleName("menubar");

		mainLayout.add(menuBar);

		//design the part for the template name and the pages handling

		HorizontalPanel captionPanel = new HorizontalPanel();
		captionPanel.setWidth("100%");

		HorizontalPanel pageHandlerPanel = new HorizontalPanel();
		pageHandlerPanel.setHeight("24");
		pageHandlerPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);

		captionPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		mainLayout.add(captionPanel);
		mainLayout.add(pageHandlerPanel);
		mainLayout.setCellHorizontalAlignment(menuBar, HasHorizontalAlignment.ALIGN_LEFT);
		mainLayout.setCellHorizontalAlignment(captionPanel, HasHorizontalAlignment.ALIGN_LEFT);
		mainLayout.setCellWidth(menuBar, "200");
		mainLayout.setCellWidth(pageHandlerPanel, "200");
		initWidget(mainLayout);
	}

	public void setMenuForWorkflowDocument(boolean canUpdate) {
		presenter.setMenuForWorkflowDocument(true);
		menuBar.removeItem(fileMenu);
		menuBar.removeItem(viewMenu);
		menuBar.removeItem(sectionsMenu);
		menuBar.removeItem(biblioMenu);
		menuBar.removeSeparator(separator1);
		menuBar.removeSeparator(separator2);
		menuBar.removeItem(exportMenu);

		MenuBar workflowMenu = new MenuBar(true);
		workflowMenu.setAnimationEnabled(true);

		MenuItem menu = new MenuItem("<nobr>Workflow Document Options</nobr>", true, workflowMenu);
		menu.setWidth("400px");
		Command updateWfDocument = new Command() {
			public void execute() {
				presenter.updateWorkflowDocument(true);
			}
		};
		Command backCommand = new Command() {
			public void execute() {
				presenter.updateWorkflowDocument(false);
			}
		};
	
		if (canUpdate)
			workflowMenu.addItem("Update this document", updateWfDocument);
		//workflowMenu.addItem("Show previous changes", showChanges);
		workflowMenu.addSeparator();
		workflowMenu.addItem("Back to My Workflow Documents", backCommand);

		menuBar.addItem(menu);
		separator1 = menuBar.addSeparator();
		viewMenu = getViewMenu();
		menuBar.addItem(viewMenu);
		separator2 = menuBar.addSeparator();
		sectionsMenu = getSectionMenu();
		menuBar.addItem(sectionsMenu);
		separator3 = menuBar.addSeparator();
		biblioMenu = getBiblioMenu();
		menuBar.addItem(biblioMenu);
		separator4 = menuBar.addSeparator();
		exportMenu = getExportsMenu();
		menuBar.addItem(exportMenu);
		ReportGenerator.get().getToolbarPanel().clear();
		ReportGenerator.get().getToolbarPanel().add(new HTML("&nbsp;&nbsp;", true));
		enableExports();
	}
	/**
	 * Redirect to VRE Deployer Portlet
	 */
	private void loadWorkflowLibraryApp(){
		getUrl();
		location += "/../my-workflow-documents";
		Window.open(location, "_self", "");		
	}
	/**
	 * Get URL from browser
	 */
	public native void getUrl()/*-{
			this.@org.gcube.portlets.user.reportgenerator.client.Headerbar::location = $wnd.location.href;
	}-*/;

	/**
	 * temporary command 
	 * @return the command instance
	 */
	public Command getNullCommand() {
		Command openNothing = new Command() {	

			public void execute() {
			}
		};
		return openNothing;
	}
	
	public Command getDisabledExportMenuItemCmd() {
		
		Command disabledExportMenuItemCmd = new Command() {	
			public void execute() {
				
				MessageBox.alert("Alert",
						"Export is disabled for templates, please save this template as a Report and retry." +
						" If you just saved this Template as a Report please save it and reopen the Report", null);
			}
		};
		return disabledExportMenuItemCmd;
	}
	/**
	 * temporary command 
	 * @return the command instance
	 */
	public Command getBiblioCommand() {
		Command openNothing = new Command() {	
			public void execute() {	
				MessageBox.alert("Warning ","A textarea must be selected to add an entry", null);
			}
		};
		return openNothing;
	}
	

	Command addCitationCmd = new Command() {	
		public void execute() {
			presenter.openAddCitationDialog();
		}
	};
	
	Command viewBiblioCmd = new Command() {	
		public void execute() {
			if (presenter.hasBibliography()) {
				presenter.seekLastPage();
			}
			else {
				MessageBox.alert("Warning", "No bibliography found, to add bibliography start adding citations:<br />Bibliography > Add citation (from within a text area)", null);
			}
		}
	};
	
	Command manageBiblioCmd = new Command() {	
		public void execute() {
			if (presenter.hasBibliography()) {
				presenter.openManageCitationsDialog();
			}
			else {
				MessageBox.alert("Warning", "No bibliography found, to add bibliography start adding citations:<br />Bibliography > Add citation (from within a text area)", null);
			}
		}
	};

	/**
	 * 
	 * @return
	 */
	private MenuItem getBiblioMenu() {
		//		Create the Options menu
		MenuBar biblioMenu = new MenuBar(true);
		MenuItem toReturn = new MenuItem("Bibliography", biblioMenu);
		biblioMenu.setAnimationEnabled(true);
		addBiblioEntry = new MenuItem("<font color=\"gray\">"+ ADD_BIBLIO_ENTRY +"</font>", true, getBiblioCommand());
		biblioMenu.addItem(addBiblioEntry);
		viewBiblio = new MenuItem(VIEW_BIBLIO, true, viewBiblioCmd);
		manageBiblio = new MenuItem(MANAGE_BIBLIO, true, manageBiblioCmd);
		biblioMenu.addSeparator();
		biblioMenu.addItem(manageBiblio);
		biblioMenu.addItem(viewBiblio);		
		return toReturn;
	}
	/**
	 * 
	 * @return
	 */
	private MenuItem getSectionMenu() {
		//		Create the Options menu
		MenuBar insertsMenu = new MenuBar(true);
		MenuItem toReturn = new MenuItem("Section", insertsMenu);
		insertsMenu.setAnimationEnabled(true);
		importModel = new MenuItem("<font color=\"gray\">Import from Template or Report</font>", true, getNullCommand());
		insertsMenu.addItem(importModel);
		viewMetadata = new MenuItem("<font color=\"gray\">View Metadata</font>", true, getNullCommand());
		discardSection = new MenuItem("<font color=\"gray\">Discard current</font>", true, getNullCommand());
		viewComments = new MenuItem("<font color=\"gray\">"+ VIEW_USER_COMMENTS+"</font>", true, getNullCommand());
		insertsMenu.addItem(discardSection);
		insertsMenu.addSeparator();
		insertsMenu.addItem(viewMetadata);
		insertsMenu.addItem(viewComments);
		return toReturn;
	}
	
	
	private MenuItem getExportsMenu() {
		MenuBar exportsMenu = new MenuBar(true);

		exportsMenu.setAnimationEnabled(true);
		MenuItem toReturn = new MenuItem("Export", exportsMenu);

		optionDOCX = new MenuItem("<font color=\"gray\">"+ EXPORT_OPENXML +"</font>", true, getDisabledExportMenuItemCmd());
		optionPDF = new MenuItem("<font color=\"gray\">Export to PDF</font>", true, getDisabledExportMenuItemCmd());
		optionHTML = new MenuItem("<font color=\"gray\">"+ EXPORT_HTML +"</font>", true, getDisabledExportMenuItemCmd());		
		optionFimes = new MenuItem("<font color=\"gray\">"+ EXPORT_FIMES +"</font>", true, getDisabledExportMenuItemCmd());
		optionXML = new MenuItem("<font color=\"gray\">"+ EXPORT_XML +"</font>", true, getDisabledExportMenuItemCmd());
		optionEncryptedModel = new MenuItem("<font color=\"gray\">"+ EXPORT_ENCRYPTED_REPORT +"</font>", true, getDisabledExportMenuItemCmd());
		
		
		exportsMenu.addItem(optionDOCX);
		exportsMenu.addItem(optionHTML);
		exportsMenu.addItem(optionPDF);
		exportsMenu.addItem(optionXML);
		exportsMenu.addSeparator();
		exportsMenu.addItem(optionEncryptedModel);
		//optionsMenu.addItem(optionPDF);
		//exportsMenu.addItem(optionFimes);
		
		return toReturn;
	}

	private MenuItem getViewMenu() {
		Command openPageProperties = new Command() {	
			public void execute() {
				int left = mainLayout.getAbsoluteLeft() + 50;
				int top = mainLayout.getAbsoluteTop() + 25;
				PagePropertiesDialog dlg = new PagePropertiesDialog(templateModel, presenter);
				dlg.setPopupPosition(left, top);
				dlg.setAnimationEnabled(true);
				dlg.show();
			}
		};

		Command showReportStructure = new Command() {			
			public void execute() {				
				presenter.showReportStructure();
			}
		};
		
		//		Create the Options menu
		MenuBar optionsMenu = new MenuBar(true);

		optionsMenu.setAnimationEnabled(true);
		MenuItem toReturn = new MenuItem("View", optionsMenu);
		
		optionsMenu.addItem("View Properties", openPageProperties);
		optionsMenu.addItem("View Structure", showReportStructure);
		optionsMenu.addSeparator();
			
		return toReturn;
	}

	/**
	 * rewrite with setHTML to remove the gray color
	 */
	public void enableExports() {

		optionDOCX.setHTML(EXPORT_OPENXML);
		optionDOCX.setCommand(generateDOCX);

		optionPDF.setHTML("Export to PDF");
		optionPDF.setCommand(generatePDF);	

		optionHTML.setHTML(EXPORT_HTML);
		optionHTML.setCommand(generateHTML);
		
		optionFimes.setHTML(EXPORT_FIMES);
		optionFimes.setCommand(generateFimes);
		
		optionXML.setHTML(EXPORT_XML);
		optionXML.setCommand(generatedXML);
		
		optionEncryptedModel.setHTML(EXPORT_ENCRYPTED_REPORT);
		optionEncryptedModel.setCommand(generateEncryptedModel);
		//
		importModel.setHTML("Import from Template or Report");
		importModel.setCommand(importModelOrReport);

		viewMetadata.setHTML("View Metadata");
		viewMetadata.setCommand(openMetadata);
		
		viewComments.setHTML(VIEW_USER_COMMENTS);
		viewComments.setCommand(showUserComments);

		discardSection.setHTML("Discard current");
		discardSection.setCommand(discardSectionCom);

	}
	/**
	 * 
	 */
	Command showUserComments = new Command() {	
		public void execute() {
			presenter.showSectionUserCommentsTooltips();
		}
	};
	/**
	 * rewrite with setHTML to remove the gray color
	 * @param d4sArea 
	 */
	public void enableBiblioEntry(RichTextArea d4sArea) {
		addBiblioEntry.setHTML(ADD_BIBLIO_ENTRY);
		addBiblioEntry.setCommand(addBiblioEntryCommand);
		presenter.setAreaForBiblio(d4sArea);
	}

	/**
	 * build the File Menu
	 * @return
	 */

	private MenuItem getFileMenu() {
		CommonCommands cmd = new CommonCommands(presenter);
		
		
		Command openHelp = new Command() {

			public void execute() {
				if (! ReportConstants.isDeployed) {
					presenter.openTemplate("", "", true);
					enableExports();
				}
				else {
					String url = "https://gcube.wiki.gcube-system.org/gcube/index.php/Common_Functionality#Report_Management";
					int width = Window.getClientWidth();
					int height = Window.getClientHeight();
					int winWidth = (int) (Window.getClientWidth() * 0.8);
					int winHeight = (int) (Window.getClientHeight() * 0.7);
					int left = (width - winWidth) / 2;
					int top = (height - winHeight) / 2;
					Window.open(url, null,"left=" + left + "top" + top + ", width=" + winWidth + ", height=" + winHeight + ", resizable=yes, scrollbars=yes, status=yes");			
				}

			}

		};

		

		Command saveReportAs = new Command() {			
			public void execute() {
				CommonCommands cmd = new CommonCommands(presenter);
				cmd.saveReportAsDialog();
			}			
		};



		Command saveReport = new Command() {			
			public void execute() {
				if (templateModel.getTemplateName().endsWith("d4sR"))
					presenter.saveReport();
				else {
					CommonCommands cmd = new CommonCommands(presenter);
					cmd.saveReportAsDialog();
				}
			}
		};

			
	

		//		Create the file menu
		MenuBar fileMenu = new MenuBar(true);
		fileMenu.setAnimationEnabled(true);

		MenuItem toReturn = new MenuItem("File", fileMenu);
		fileMenu.addItem("Open Report", cmd.openReport);
		fileMenu.addItem("Open template...", cmd.openTemplate);
		fileMenu.addSeparator();		
		fileMenu.addItem("Save", saveReport);
		fileMenu.addItem("Save As ..", saveReportAs);
		fileMenu.addSeparator();
//		fileMenu.addItem("Import from FiMES XML", importFimes);
		fileMenu.addItem("Close Report", cmd.newTemplate);
		fileMenu.addSeparator();
		fileMenu.addItem("? Open User's Guide", openHelp);		
		return toReturn;
	}

	/**
	 * 
	 * @param model .
	 */
	public void setModel(TemplateModel model ) {
		this.templateModel = model;
	}

	//************** COMMANDS ********************************////
	
	Command generateFimes = new Command() {	
		public void execute() {
			presenter.generateFiMES(templateModel);
		}
	};
	
	Command generateDOCX = new Command() {	
		public void execute() {
			presenter.generateManifestation(templateModel, ExportManifestationType.DOCX);
		}
	};

	Command generatePDF = new Command() {	
		public void execute() {
//			Window.alert("PDF Exporting may not be fully working, you can also generate a PDF using your Word Processor application starting from the docx exported file");
			presenter.generateManifestation(templateModel, ExportManifestationType.PDF);
		}
	};

	Command generateHTML = new Command() {	
		public void execute() {
			presenter.generateManifestation(templateModel, ExportManifestationType.HTML);
		}
	};
	
	Command generatedXML = new Command() {
		public void execute() {
			presenter.generateManifestation(templateModel, ExportManifestationType.XML);
		}
	};
	
	Command generateEncryptedModel = new Command() {		
		@Override
		public void execute() {					
			GWT.runAsync(WorkspaceLightTreeLoadPopup.class, new RunAsyncCallback() {
				public void onSuccess() {
					WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Select the Report (or Template) to encrypt ", true, true);
					wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE, ItemType.REPORT);
					wpTreepopup.setSelectableTypes(ItemType.REPORT_TEMPLATE, ItemType.REPORT);

					wpTreepopup.addPopupHandler(new PopupHandler() {
						public void onPopup(PopupEvent event) {
							if (! event.isCanceled()) {
								if (event.getSelectedItem() != null) {
									final String itemId = event.getSelectedItem().getId();
									final String url = GWT.getModuleBaseURL() + "downloadEncryptedReport?itemId=" + itemId; 
									Window.open(url, "_blank", "");												
								}			
							}

						}
					});

					wpTreepopup.center();
					wpTreepopup.show();
				}

				public void onFailure(Throwable reason) {
					Window.alert("There are networks problem, please check your connection.");              
				}
			});
		}
	};
	

	Command discardSectionCom = new Command() {	
		public void execute() {
			presenter.discardCurrentSection();
		}
	};
	
	//************** COMMANDS ********************************////
	Command addBiblioEntryCommand = new Command() {	
		public void execute() {
			GWT.runAsync(new RunAsyncCallback() {
				
				@Override
				public void onSuccess() {
					presenter.openAddCitationDialog();					
				}
				
				@Override
				public void onFailure(Throwable reason) {		
				}
			});
			
		}
	};

	/**
	 * 
	 */
	Command openMetadata =  new Command() {			
		public void execute() {	
			GWT.runAsync(new RunAsyncCallback() {
				
				@Override
				public void onSuccess() {
					int left = mainLayout.getAbsoluteLeft() + 50;
					int top = mainLayout.getAbsoluteTop() + 25;
					GCubeDialog dlg = new GCubeDialog(true);
					dlg.setText("Report Metadata:");
					int pageNo = presenter.getModel().getCurrentPage();
					List<Metadata> metadatas =  presenter.getModel().getSection(pageNo).getAllMetadata();
					int nRows = metadatas.size();
					Grid metadataGrid = new Grid(nRows, 2);
					int i = 0;
					for (Metadata md : metadatas) {
						metadataGrid.setWidget(i, 0, new HTML("<b>" + md.getAttribute() + ": </b>"));
						metadataGrid.setWidget(i, 1, new HTML(md.getValue()));
						i++;
					}

					dlg.setWidget(metadataGrid);
					dlg.setPopupPosition(left, top);
					dlg.setAnimationEnabled(true);
					dlg.show();					
				}
				
				@Override
				public void onFailure(Throwable reason) {}
			});
			
			
		}
	};

	Command importModelOrReport = new Command() {			
		public void execute() {
			if (! ReportConstants.isDeployed) {
				int left = mainLayout.getAbsoluteLeft() + 50;
				int top = mainLayout.getAbsoluteTop() + 25;
				ImporterDialog dlg = new ImporterDialog(null, presenter);
				dlg.setPopupPosition(left, top);
				dlg.setAnimationEnabled(true);
				dlg.show();
			}
			else {
				GWT.runAsync(new RunAsyncCallback() {
					@Override
					public void onSuccess() {
						int left = mainLayout.getAbsoluteLeft() + 50;
						int top = mainLayout.getAbsoluteTop() + 25;
						WorkspaceLightTreeLoadPopup wpTreepopup = new WorkspaceLightTreeLoadPopup("Pick the item you want to import from", true, true);
						wpTreepopup.setShowableTypes(ItemType.REPORT_TEMPLATE, ItemType.REPORT);			

						wpTreepopup.addPopupHandler(new PopupHandler() {
							public void onPopup(PopupEvent event) {
								if (! event.isCanceled()) {
									if (event.getSelectedItem() != null) {
										int left = mainLayout.getAbsoluteLeft() + 50;
										int top = mainLayout.getAbsoluteTop() + 25;
										ImporterDialog dlg = new ImporterDialog(event.getSelectedItem(), presenter);
										dlg.setPopupPosition(left, top);
										dlg.setAnimationEnabled(true);
										dlg.show();
									}	
									presenter.getHeader().enableExports();			
								}

							}
						});
						wpTreepopup.setPopupPosition(left, top);
						wpTreepopup.show();						
					}
					
					@Override
					public void onFailure(Throwable reason) {
						
					}
				});
				
			}
		}	
	};
	/**
	 * 
	 * @return .
	 */
	public CellPanel getMainLayout() {
		return mainLayout;
	}
}
