package eu.dnetlib.client.shared;

import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sencha.gxt.widget.core.client.AutoProgressBar;
import com.sencha.gxt.widget.core.client.Dialog.PredefinedButton;
import com.sencha.gxt.widget.core.client.box.MessageBox;
import com.sencha.gxt.widget.core.client.container.AbstractHtmlLayoutContainer.HtmlData;
import com.sencha.gxt.widget.core.client.container.HtmlLayoutContainer;
import com.sencha.gxt.widget.core.client.event.HideEvent;
import com.sencha.gxt.widget.core.client.event.HideEvent.HideHandler;

import eu.dnetlib.client.GreetingService;
import eu.dnetlib.client.GreetingServiceAsync;
import eu.dnetlib.client.resources.item.ItemEditPanel;
import eu.dnetlib.client.resources.theme.ThemesForm;
import gwtupload.client.IFileInput.FileInputType;
import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.IUploader;
import gwtupload.client.IUploader.OnFinishUploaderHandler;
import gwtupload.client.IUploader.OnStartUploaderHandler;
import gwtupload.client.IUploader.UploadedInfo;
import gwtupload.client.SingleUploader;

public class GWTUpload extends Composite {
	private static Logger log = Logger.getLogger("GWTUpload");

	private VerticalPanel vPanel = new VerticalPanel();

	private final GreetingServiceAsync Service = GWT.create(GreetingService.class);

	private String mediaId;
	private String[] validExtensions = { "jpg", "png", "jpeg", "gif", "bmp", "mp4", "mpeg", "webm", "mpg" };
	private String[] validExtensionsOnlyImages = { "jpg", "png", "jpeg", "gif", "bmp" };
	private String[] validExtensionsOnlyVideos = { "mp4", "mpeg", "webm", "mpg" };

	private String miniImage;
	private String mediumImage;

	// file info
	private String type = null;
	private boolean thumbChanged;
	private String servletPath = "servlet.gupld";
	private String parameter = "";
	private String maxSize = "";

	private ItemEditPanel itemEditPanel;
	private ThemesForm themesForm;
	private final SingleUploader defaultUploader;
	private AutoProgressBar progressBar = new AutoProgressBar();

	private MessageBox progressMessage = new MessageBox("Uploading...");
	private Button cancel = new Button("Cancel");
	private boolean canceled = false;
	private boolean isImage = false;

	private IUploader.OnFinishUploaderHandler onFinishUploaderHandlerForNewItem = new IUploader.OnFinishUploaderHandler() {
		public void onFinish(IUploader uploader) {
			cancel.setVisible(false);
			log.info("*********item source *************  OnFinishUploaderHandler **************** " + uploader.getStatus());
			if (uploader.getStatus() == Status.SUCCESS) {

				// The server sends useful information to the client by default
				UploadedInfo info = uploader.getServerInfo();
				if (info.message.contains("TOOBIG")) {
					final MessageBox warning = new MessageBox(" Warning", "Upload failed. This file is too big.");

					warning.setPredefinedButtons(PredefinedButton.OK);
					warning.setIcon(MessageBox.ICONS.warning());
					warning.setMinHeight(100);

					warning.show();
					itemEditPanel.previewSourceFail();
					return;
				}
				if (canceled) {
					onCancelDeleteUploads(uploader.getServerInfo().message);
					itemEditPanel.previewSourceFail();
					return;
				}
				log.info("File name " + info.name);
				log.info("File content-type " + info.ctype);
				type = info.ctype;
				log.info("File size " + info.size);

				// You can send any customized message and parse it
				log.info("Server message " + info.message);
				thumbChanged = true;
				if (info.message.split("_").length == 3) {
					mediaId = info.message.split("_")[0];
					miniImage = info.message.split("_")[1];
					mediumImage = info.message.split("_")[2];
					log.info(".........media:: ... " + mediaId);

					log.info(".........mini:: ... " + miniImage);
					log.info(".........medium:: ... " + mediumImage);

				} else {
					mediaId = info.message;
				}
				if (isImage) {
					itemEditPanel.previewImageSource();
				} else {
					itemEditPanel.previewVideoSource();
				}
			} else if (uploader.getStatus() == Status.CANCELED || uploader.getStatus() == Status.CANCELING) {
				onCancelDeleteUploads(uploader.getServerInfo().message);
				itemEditPanel.previewSourceFail();

			}
		}
	};

	private IUploader.OnFinishUploaderHandler onFinishUploaderHandlerForUpdateMini = new IUploader.OnFinishUploaderHandler() {
		public void onFinish(IUploader uploader) {
			log.info("*********item mini *************  OnFinishUploaderHandler **************** " + uploader.getStatus());
			if (uploader.getStatus() == Status.SUCCESS) {

				// The server sends useful information to the client by default
				UploadedInfo info = uploader.getServerInfo();
				if (info.message.contains("TOOBIG")) {
					final MessageBox warning = new MessageBox(" Warning", "Upload failed. This file is too big.");

					warning.setPredefinedButtons(PredefinedButton.OK);
					warning.setIcon(MessageBox.ICONS.warning());
					warning.setMinHeight(100);
					warning.show();
					itemEditPanel.setEnableButtons(true);
					return;
				}
				if (canceled) {
					onCancelDeleteUploads(uploader.getServerInfo().message);
					itemEditPanel.setEnableButtons(true);
					return;
				}
				log.info("File name " + info.name);
				log.info("File content-type " + info.ctype);
				type = info.ctype;
				log.info("File size " + info.size);
				// You can send any customized message and parse it
				log.info("Server message " + info.message);
				thumbChanged = true;
				if (info.message.split("_").length == 2) {
					miniImage = info.message.split("_")[0];
					mediumImage = info.message.split("_")[1];
					log.info(".........mini:: ... " + miniImage);
					log.info(".........medium:: ... " + mediumImage);

				}
				itemEditPanel.previewMiniMedia();

			} else if (uploader.getStatus() == Status.CANCELED || uploader.getStatus() == Status.CANCELING) {
				onCancelDeleteUploads(uploader.getServerInfo().message);
				itemEditPanel.setEnableButtons(true);

			}
		}
	};
	private IUploader.OnFinishUploaderHandler onFinishUploaderHandlerForThemeMini = new IUploader.OnFinishUploaderHandler() {
		public void onFinish(IUploader uploader) {
			log.info("*********theme mini *************  OnFinishUploaderHandler **************** " + uploader.getStatus());
			if (uploader.getStatus() == Status.SUCCESS) {

				// The server sends useful information to the client by default
				UploadedInfo info = uploader.getServerInfo();
				if (info.message.contains("TOOBIG")) {
					final MessageBox warning = new MessageBox(" Warning", "Upload failed. This file is too big.");

					warning.setPredefinedButtons(PredefinedButton.OK);
					warning.setIcon(MessageBox.ICONS.warning());
					warning.setMinHeight(100);
					warning.show();
					themesForm.setEnableButtons(true);
					themesForm.emptyThumbnailPanel();
					return;
				}
				if (canceled) {
					onCancelDeleteUploads(uploader.getServerInfo().message);
					themesForm.setEnableButtons(true);
					return;
				}
				log.info("File name " + info.name);
				log.info("File content-type " + info.ctype);
				type = info.ctype;
				log.info("File size " + info.size);
				// You can send any customized message and parse it
				log.info("Server message " + info.message);
				thumbChanged = true;
				miniImage = info.message;
				log.info(".........mini:: ... " + miniImage);
				themesForm.previewThumbnail();

			} else if (uploader.getStatus() == Status.CANCELED || uploader.getStatus() == Status.CANCELING) {
				log.info("************canceling   " + uploader.getStatus());
				onCancelDeleteUploads(uploader.getServerInfo().message);
				themesForm.setEnableButtons(true);

			}

		}
	};
	private IUploader.OnCancelUploaderHandler onCancelUploaderHandler = new IUploader.OnCancelUploaderHandler() {

		public void onCancel(IUploader uploader) {
		}
	};

	private GWTUpload() {
		defaultUploader = new SingleUploader(FileInputType.BROWSER_INPUT);
		defaultUploader.addStyleName("gwtUpload");
		defaultUploader.setTitle("Click to select a file...");
		progressBar.getCell().setProgressText("Uploading...");
		progressBar.auto();
		progressBar.show();
		FlowPanel fp = new FlowPanel();
		fp.add(new HTML("Please wait..."));

		fp.add(progressBar);
		progressMessage.add(fp);
		progressMessage.setPredefinedButtons(PredefinedButton.CANCEL);
		progressMessage.addHideHandler(new HideHandler() {

			public void onHide(HideEvent event) {
				if (progressMessage.getHideButton() == null) {
					return;
				}
				String buttonText = progressMessage.getHideButton().getText();
				if (buttonText.equals("Cancel")) {
					log.info("\n\n\n\n on hide Cancel  clicked!!!!!!!!!!\n\n\n");
					cancelUpload();
				}

				else {
					// do nothing
				}
			}
		});
		defaultUploader.getStatusWidget().getWidget().removeFromParent();

		defaultUploader.getFileInput().setLength(20);
		defaultUploader.setAutoSubmit(true);
		vPanel.add(defaultUploader);

		initWidget(vPanel);
		defaultUploader.setValidExtensions(validExtensions);
		defaultUploader.addOnStartUploadHandler(new OnStartUploaderHandler() {

			public void onStart(IUploader uploader) {
				canceled = false;

				progressBar.getCell().setProgressText("Uploading...");
				progressBar.auto();
				progressBar.show();

				progressMessage.center();
				progressMessage.show();
			}
		});
		defaultUploader.addOnFinishUploadHandler(new OnFinishUploaderHandler() {

			public void onFinish(IUploader uploader) {
				progressMessage.hide();

			}
		});
		defaultUploader.addOnCancelUploadHandler(onCancelUploaderHandler);

	}

	public GWTUpload(final boolean isSource, boolean isImage, ItemEditPanel itemEditPanel, String size) {
		this();
		this.itemEditPanel = itemEditPanel;
		this.isImage = isImage;
		if (isSource) {

			parameter = "?source=itemSource";
			if(isImage){
				defaultUploader.setValidExtensions(validExtensionsOnlyImages);
				
			}else{
				defaultUploader.setValidExtensions(validExtensionsOnlyVideos);
				
			}
		} else {
			parameter = "?source=itemMini";
			defaultUploader.setValidExtensions(validExtensionsOnlyImages);

		}

		maxSize = "size=" + size;
		defaultUploader.setServletPath(servletPath + parameter + maxSize);

		// Add a finish handler which will load the image once the upload
		// finishes
		if (isSource) {
			defaultUploader.addOnFinishUploadHandler(onFinishUploaderHandlerForNewItem);
			mediaId = "";
		} else {
			defaultUploader.addOnFinishUploadHandler(onFinishUploaderHandlerForUpdateMini);
			miniImage = "";
			mediumImage = "";
		}
		defaultUploader.addOnStartUploadHandler(new OnStartUploaderHandler() {

			public void onStart(IUploader uploader) {

				removePreviousUploadForItemSource();
                if(isSource) {
                    GWTUpload.this.itemEditPanel.getEmbeddedVideoItem().clear(true);
                }
				GWTUpload.this.itemEditPanel.setEnableButtons(false);
			}
		});
	}

	public GWTUpload(ThemesForm themesForm, String size) {
		this();

		this.themesForm = themesForm;
		defaultUploader.setValidExtensions(validExtensionsOnlyImages);
		parameter = "?source=themeMini";
		maxSize = "size=" + size;

		defaultUploader.setServletPath(servletPath + parameter + maxSize);

		// Add a finish handler which will load the image once the upload
		// finishes
		defaultUploader.addOnFinishUploadHandler(onFinishUploaderHandlerForThemeMini);
		defaultUploader.addOnStartUploadHandler(new IUploader.OnStartUploaderHandler() {
			public void onStart(IUploader uploader) {

				removePreviousMini();
				GWTUpload.this.themesForm.setEnableButtons(false);
			}
		});
		miniImage = "";
	}

	public void cancelUpload() {
		defaultUploader.cancel();
		cancel.setEnabled(false);
		progressBar.getCell().setProgressText("Canceling...");

	}

	public void onCancelDeleteUploads(String message) {
		log.info("\n\ncancel action " + message + "\n\n  ");
		canceled = true;
		progressBar.getCell().setProgressText("Canceling...");

		if (message != null) {
			for (int i = 0; i < message.split("_").length; i++) {
				log.info("split  " + message.split("_")[i]);

				if (!message.split("_")[i].equals("ERROR")) {
					Service.deleteMedia(message.split("_")[i], new AsyncCallback<String>() {

						public void onFailure(Throwable caught) {
							log.info(" on cancel-media delete failed" + caught.getMessage());

						}

						public void onSuccess(String b) {
							log.info(" on cancel-media  DELETEEED");
						}
					});

				}
			}
		}

	}

	public void removePreviousUploadForItemSource() {
		if (this.mediaId != null && !this.mediaId.isEmpty()) {

			log.info("REMOVE previous upload");
			String mediatoDelete = new String(mediaId + "");
			this.Service.deleteMedia(mediatoDelete, new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					log.info(" item source delete failed" + caught.getMessage());

				}

				public void onSuccess(String b) {
					log.info(" source DELETEEED");
				}
			});

			itemEditPanel.setSourceImage();
			itemEditPanel.setSourceMediaId(null);

			this.mediaId = "";
			itemEditPanel.setMiniImage(null);

			if (type.contains("image")) {

				removePreviousThumbUpload();
				itemEditPanel.setMiniImage(null);
				itemEditPanel.setMediumImage(null);
				itemEditPanel.getThumbImagePanel().clear();

				itemEditPanel.setThumbImage();
			}

		} else {
			if (this.miniImage != null && !this.miniImage.isEmpty()) {
				removePreviousThumbUpload();
				itemEditPanel.setMiniImage(null);
				itemEditPanel.setMediumImage(null);
				itemEditPanel.setThumbImage();
			}
		}

	}

	public void removePreviousThumbUpload() {
		removePreviousMini();
		removePreviousMidi();
	}

	public void removePreviousMini() {
		if (this.miniImage != null && !this.miniImage.isEmpty()) {

			log.info("REMOVE previous upload");
			String minitoDelete = new String(miniImage + "");
			this.Service.deleteMedia(minitoDelete, new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					log.info(" mini media delete failed" + caught.getMessage());

				}

				public void onSuccess(String b) {
					log.info("mini DELETEEED");
				}
			});
			if (themesForm != null) {
				themesForm.emptyThumbnailPanel();

			}

			this.miniImage = "";

		}
	}

	public void removePreviousMidi() {

		if (this.mediumImage != null && !this.mediumImage.isEmpty()) {

			log.info("REMOVE previous upload");
			String miditoDelete = new String(mediumImage + "");
			this.Service.deleteMedia(miditoDelete, new AsyncCallback<String>() {

				public void onFailure(Throwable caught) {
					log.info("    medium media delete failed" + caught.getMessage());

				}

				public void onSuccess(String b) {
					log.info("medium DELETEEED");
				}
			});
			if (itemEditPanel != null && itemEditPanel.getMediaType() != null && itemEditPanel.getMediaType().contains("video")&&itemEditPanel.getExternalLink()==null&&itemEditPanel.getEmbeddedLink()==null) {
				itemEditPanel.getSourceFiles().getUploadedVideoPanel().clear();
				VideoHtml video = new VideoHtml(itemEditPanel.getSourceMediaId(), itemEditPanel.getMediaType(), null);
				itemEditPanel.getSourceFiles().getUploadedVideoPanel().add(video);
				VideoHtml.displayplayer();

			}

			this.mediumImage = "";

		}

	}

	public String getType() {
		return this.type;
	}

	public String getItemId() {
		return this.mediaId;
	}

	public void setThumbChanged(boolean changed) {
		this.thumbChanged = changed;
	}

	public boolean isThumbChanged() {
		return this.thumbChanged;
	}

	class HugeFileDialogBox {
		private PopupPanel hugefile = new PopupPanel();

		public HugeFileDialogBox() {
			hugefile.setStyleName("confirmBox");
			HtmlLayoutContainer con = new HtmlLayoutContainer(getTableMarkup());
			con.add(new HTML("<br>File size is bigger than 20MB. <br>Please upload another file.<br><br>"), new HtmlData(".text"));
			Button close = new Button("OK");
			close.addClickHandler(new ClickHandler() {

				public void onClick(ClickEvent arg0) {
					hugefile.hide();
				}
			});
			con.add(close, new HtmlData(".close"));
			hugefile.add(con);
		}

		public void center() {
			hugefile.center();
		}

		private native String getTableMarkup() /*-{
												return [
												'<table width=100% cellpadding=0 cellspacing=10>',
												
												'<tr> <td class=text></td> </tr>',
												'<tr> <td class=close></td> </tr>',
												
												'</table>'

												].join("");
												}-*/;

	}

	public void updateSize(String size) {
		maxSize = "size=" + size;

		defaultUploader.setServletPath(servletPath + parameter + maxSize);

	}

	public String getMediaId() {
		return mediaId;
	}

	public void setMediaId(String mediaId) {
		this.mediaId = mediaId;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getMiniImage() {
		return miniImage;
	}

	public String getMediumImage() {
		return mediumImage;
	}

	public void setMiniImage(String miniImage) {
		this.miniImage = miniImage;
	}

	public void setMediumImage(String mediumImage) {
		this.mediumImage = mediumImage;
	}

	public SingleUploader getDefaultUploader() {
		return defaultUploader;
	}

}