package org.inria.bmajwatcher.client.ui.bank_editor;

import java.util.HashMap;
import java.util.Map;

import org.inria.bmajwatcher.client.services.SiteManagerServiceAsync;
import org.inria.bmajwatcher.client.ui.styles.MainCss;
import org.inria.bmajwatcher.client.ui.styles.Resources;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
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.DialogBox;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.smartgwt.client.util.SC;

/**
 * Shows site manager window.
 * Allows to add a add/modify/delete a remote repository.
 * 
 * @author rsabas
 *
 */
public class SiteManagerDialog extends DialogBox {

	private MainCss css = Resources.INSTANCE.mainCss();
	private Map<String, String> sites = new HashMap<String, String>();
	private ListBox listSites = new ListBox(false);
	
	private String selectedUrl = "";
	
	public SiteManagerDialog(final String enteredUrl) {
		super(false, true);
		
		addStyleName(css.bankEditor());
		setHTML("<b>Site manager</b>");
	
		VerticalPanel vpDetail = new VerticalPanel();
		vpDetail.addStyleName(css.siteManagerDetail());
		VerticalPanel vpList = new VerticalPanel();
		vpList.addStyleName(css.siteManagerList());
		HorizontalPanel hpContent = new HorizontalPanel();
		HorizontalPanel hpButtons = new HorizontalPanel();
		hpButtons.addStyleName(css.siteManagerButtons());
		hpButtons.setSpacing(3);
		VerticalPanel vpMain = new VerticalPanel();
		
		
		
		hpContent.add(vpDetail);
		hpContent.add(vpList);
		
		Label urlTitle = new Label("Url");
		urlTitle.addStyleName(css.siteManagerTitle());
		vpDetail.add(urlTitle);
		final TextBox txtUrl = new TextBox();
		txtUrl.setSize("200px", "28px");
		vpDetail.add(txtUrl);
		
		Label descriptionTitle = new Label("Description");
		descriptionTitle.addStyleName(css.siteManagerTitle());
		vpDetail.add(descriptionTitle);
		final TextArea txtDescription = new TextArea();
		txtDescription.setSize("200px", "70px");
		vpDetail.add(txtDescription);
		
		listSites.setHeight("130px");
		
		listSites.addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				String url = listSites.getItemText(listSites.getSelectedIndex());
				txtUrl.setText(url);
				txtDescription.setText(sites.get(url));
			}
		});
		
		/*
		 * SELECT SITE
		 */
		Button btSelect = new Button("Select");
		btSelect.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				selectedUrl = txtUrl.getText();
				hide();
			}
		});
		
		/*
		 * SAVE SITE
		 */
		Button btSave = new Button("Save");
		btSave.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				final String url = txtUrl.getText().trim();
				if (!url.isEmpty()) {
					boolean updated = false;
					for (int i = 0; i < listSites.getItemCount() && !updated; i++) {
						if (listSites.getItemText(i).equals(url)) {
							SiteManagerServiceAsync.INSTANCE.updateSite(url, url, txtDescription.getText().trim(), new AsyncCallback<Boolean>() {

								@Override
								public void onFailure(Throwable caught) {
									SC.warn("RPC call failure");
								}

								@Override
								public void onSuccess(Boolean result) {
									if (!result) {
										SC.warn("Update site failure");
									} else {
										sites.put(url, txtDescription.getText().trim());
									}
								}
							});
							updated = true;
						}
					}
					if (!updated) {
						SiteManagerServiceAsync.INSTANCE.addSite(url, txtDescription.getText().trim(), new AsyncCallback<Boolean>() {
							
							@Override
							public void onSuccess(Boolean result) {
								if (!result)
									SC.warn("Add site failed");
								else {
									if (!url.startsWith("http://"))
										sites.put("http://" + url, txtDescription.getText().trim());
									else
										sites.put(url, txtDescription.getText().trim());
									refreshList();
								}
							}
							
							@Override
							public void onFailure(Throwable caught) {
								SC.warn("RPC call failure");
							}
						});
					}
				}
			}
		});
		
		/*
		 * CLOSE WINDOW
		 */
		Button btCancel = new Button("Cancel");
		btCancel.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				hide();
			}
		});
		
		/*
		 * DELETE SITE
		 */
		Button btDelete = new Button("Delete");
		btDelete.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				final String url = txtUrl.getText();
				SiteManagerServiceAsync.INSTANCE.deleteSite(url, new AsyncCallback<Boolean>() {
					
					@Override
					public void onSuccess(Boolean result) {
						if (!result)
							SC.warn("Deletion failed");
						else {
							sites.remove(url);
							refreshList();
						}
					}
					
					@Override
					public void onFailure(Throwable caught) {
						SC.warn("RPC failure");
					}
				});
			}
		});
		
		hpButtons.add(btSelect);
		hpButtons.add(btSave);
		hpButtons.add(btDelete);
		hpButtons.add(btCancel);
		
		listSites.setVisibleItemCount(7);
		
		/*
		 * LOADING SITES
		 */
		SiteManagerServiceAsync.INSTANCE.getSites(new AsyncCallback<Map<String,String>>() {
			
			@Override
			public void onSuccess(Map<String, String> result) {
				sites = result;
				int i = 0;
				int selectedIndex = -1;
				for (String key : result.keySet()) {
					if (key.equals(enteredUrl)) {
						txtUrl.setText(key);
						txtDescription.setText(result.get(key));
						selectedIndex = i;
					}
					listSites.addItem(key, key);
					i++;
				}
				if (selectedIndex >= 0) {
					listSites.setSelectedIndex(selectedIndex);
				} else if (i > 0) {
					listSites.setSelectedIndex(0);
					String url = listSites.getItemText(0);
					txtUrl.setText(url);
					txtDescription.setText(result.get(url));
				}
			}
			
			@Override
			public void onFailure(Throwable caught) {
				SC.warn("Sites loading failure");
			}
		});
		
		Label listTitle = new Label("Saved sites");
		listTitle.addStyleName(css.siteManagerTitle());
		vpList.add(listTitle);
		vpList.add(listSites);
		
		vpMain.add(hpContent);
		vpMain.add(hpButtons);
		vpMain.setCellHorizontalAlignment(hpButtons, HasHorizontalAlignment.ALIGN_CENTER);
		add(vpMain);
	}
	
	private void refreshList() {
		listSites.clear();
		for (String key : sites.keySet()) {
			listSites.addItem(key, key);
		}
	}
	
	public String getSelectedUrl() {
		return selectedUrl;
	}
}
