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

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

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

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;


/**
 * Component for building bank dependencies.
 * 
 * @author rsabas
 *
 */
public class BankDependencyBuilder {
	
	private ListBox refList;
	private String dbSource = "";
	private String refRelease = "";
	private Panel container;
	private MainCss css = Resources.INSTANCE.mainCss();
	private Map<ListBox, TextBox> dependenciesValues = new HashMap<ListBox, TextBox>();
	private Map<String, String> values = new HashMap<String, String>();
	private HorizontalPanel hpRefRelease = new HorizontalPanel();
	private TextBox tbRefRelease = new TextBox();
	
	public BankDependencyBuilder(ListBox list) {
		refList = list;
	}
	
	private void init() {
		hpRefRelease.clear();
		hpRefRelease.setVisible(false);
		container = new VerticalPanel();
		container.addStyleName(css.dependencyMainPanel());
		dependenciesValues.clear();
		
		VerticalPanel subPanel = new VerticalPanel();
		subPanel.addStyleName(css.dependencyTopPanel());
		final VerticalPanel dependencies = new VerticalPanel();
		dependencies.addStyleName(css.dependency100Panel());
		subPanel.add(dependencies);
		subPanel.add(new Button("New dependency", new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dependencies.add(buildDependPanel("", ""));
			}
		}));
		
		if (!dbSource.trim().isEmpty()) {
			String[] sources = dbSource.split(",");
			for (String bk: sources) {
				String value = values.get("misc__" + bk + ".files.move");
				if (value != null)
					dependencies.add(buildDependPanel(bk, value));
				else
					dependencies.add(buildDependPanel(bk, ""));
			}
			tbRefRelease.setText(refRelease);
		}
		
		container.add(subPanel);
		
		Label lblRef = new Label("Retrieve release from bank :");
		hpRefRelease.add(lblRef);
		hpRefRelease.add(tbRefRelease);
		hpRefRelease.setCellVerticalAlignment(lblRef, HasVerticalAlignment.ALIGN_MIDDLE);
		container.add(hpRefRelease);
	}
	
	private Panel buildDependPanel(String selectedBank, String filesToMove) {
		
		hpRefRelease.setVisible(true);
		
		final HorizontalPanel hpDepend = new HorizontalPanel();
		hpDepend.addStyleName(css.dependency100Panel());
		
		PushButton btnRemove = new PushButton(new Image("images/edit-delete.png"));
		btnRemove.addStyleName(css.removePropertyButton());
		hpDepend.add(btnRemove);
		hpDepend.setCellWidth(btnRemove, "16px");
		
		VerticalPanel vpContent = new VerticalPanel();
		vpContent.addStyleName(css.dependencyPanel());
		
		HorizontalPanel hpSelect = new HorizontalPanel();
		Label lblDepends = new Label("Depends bank");
		hpSelect.add(lblDepends);
		final ListBox lb = getListBox(selectedBank);
		hpSelect.add(lb);
		hpSelect.setCellWidth(lblDepends, "150px");
		hpSelect.setCellVerticalAlignment(lblDepends, HasVerticalAlignment.ALIGN_MIDDLE);
		
		vpContent.add(hpSelect);
		
		HorizontalPanel hpFiles = new HorizontalPanel();
		Label lblMove = new Label("Files to move");
		hpFiles.add(lblMove);
		TextBox tb = new TextBox();
		tb.setText(filesToMove);
		hpFiles.add(tb);
		hpFiles.setCellWidth(lblMove, "150px");
		hpFiles.setCellVerticalAlignment(lblMove, HasVerticalAlignment.ALIGN_MIDDLE);
		
		vpContent.add(hpFiles);
		
		hpDepend.add(vpContent);
		
		btnRemove.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dependenciesValues.remove(lb);
				if (dependenciesValues.size() == 0)
					hpRefRelease.setVisible(false);
				hpDepend.removeFromParent();
			}
		});
		
		dependenciesValues.put(lb, tb);
		
		return hpDepend;
	}
	
	public DisclosurePanel getDependencyPanel() {
		init();
		
		DisclosurePanel dp = new DisclosurePanel("Bank dependencies");
		dp.addStyleName(css.dependency100Panel());
		dp.add(container);
		
		return dp;
	}
	
	private ListBox getListBox(String selectedBank) {
		ListBox lb = new ListBox(false);
		int selectedIndex = 0;
		for (int i = 0; i < refList.getItemCount(); i++) {
			if (refList.getItemText(i).equals(selectedBank))
				selectedIndex = i;
			
			lb.addItem(refList.getItemText(i));
		}
		lb.setSelectedIndex(selectedIndex);
		
		return lb;
		
	}
	
	public Map<String, String> getParameters() {
		Map<String, String> res = new HashMap<String, String>();
		String bankList = "";
		for (ListBox lb : dependenciesValues.keySet()) {
			String value = lb.getItemText(lb.getSelectedIndex());
			
			if (!value.trim().isEmpty()) {
				bankList += value + ",";
				if (!dependenciesValues.get(lb).getText().trim().isEmpty())
					res.put("misc__" + value + ".files.move", dependenciesValues.get(lb).getText().trim());
			}
		}
		if (bankList.trim().length() > 0) {
			res.put("misc__db.source", bankList.substring(0, bankList.length() - 1));
			if (!tbRefRelease.getText().trim().isEmpty())
				res.put("misc__ref.release", tbRefRelease.getText().trim());
		}
		
		return res;
	}

	public void addParameterValue(String key, String value) {
		values.put(key, value);
	}
	
	public void setDbSource(String banks) {
		dbSource = banks;
	}
	
	public void setRefRelease(String ref) {
		refRelease = ref;
	}

	public boolean isEmpty() {
		return dependenciesValues.size() == 0;
	}
}
