package com.sbs.jpm.client;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.EntryPoint;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.DSOperationType;
import com.smartgwt.client.types.FieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.TextMatchStyle;
import com.smartgwt.client.types.TileLayoutPolicy;
import com.smartgwt.client.util.EventHandler;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.KeyPressEvent;
import com.smartgwt.client.widgets.events.KeyPressHandler;
import com.smartgwt.client.widgets.events.MouseMoveEvent;
import com.smartgwt.client.widgets.events.MouseMoveHandler;
import com.smartgwt.client.widgets.events.MouseOutEvent;
import com.smartgwt.client.widgets.events.MouseOutHandler;
import com.smartgwt.client.widgets.events.MouseOverEvent;
import com.smartgwt.client.widgets.events.MouseOverHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.grid.EditorValueMapFunction;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tile.CreateTileCustomizer;
import com.smartgwt.client.widgets.tile.SimpleTile;
import com.smartgwt.client.widgets.tile.TileGrid;
import com.smartgwt.client.widgets.tree.TreeGridField;
import com.smartgwt.client.widgets.viewer.DetailViewerField;

public class TestCase implements EntryPoint {

	private Panel panel;
	private TestDataSource dataSource;

	public void onModuleLoad() {

		SC.showConsole();

		dataSource = new TestDataSource();

		panel = new Panel();
		panel.setWidth100();
		panel.setHeight100();

		panel.draw();
	}

	public class Panel extends VLayout {

		private ListGrid grid;
		private TileGrid tileGrid;
		private TreeGridField nameGridField;
		private TreeGridField startDateField;

		private HLayout rollOverCanvas;

		public Panel() {

			nameGridField = new TreeGridField();
			nameGridField.setName(TestDataSource.NAME_FIELD);
			nameGridField.setTitle("Name");

			startDateField = new TreeGridField();
			startDateField.setName(TestDataSource.START_DATE_FIELD);
			startDateField.setTitle("Start date");

			ListGridField divisionField = new ListGridField("division", "Division");
			SelectItem divisionSelectItem = new SelectItem();
			divisionSelectItem.setValueMap("Marketing", "Sales", "Services");
			divisionSelectItem.addChangedHandler(new ChangedHandler() {
				public void onChanged(ChangedEvent event) {
					// calling 'setValueMap()' will force the 'getEditorValueMap' method to be
					// re-evaluated for the department field
					grid.setValueMap("department", new LinkedHashMap());
				}
			});
			divisionField.setEditorProperties(divisionSelectItem);

			ListGridField departmentField = new ListGridField("department", "Department");

			final Map<String, String[]> departments = new HashMap<String, String[]>();
			departments.put("Marketing", new String[] { "Advertising", "Community Relations" });
			departments.put("Sales", new String[] { "Channed Sales", "Direct Sales" });
			departments.put("Manufacturing", new String[] { "Design", "Development", "QA" });
			departments.put("Services", new String[] { "Support", "Consulting" });

			SelectItem departmentSelectItem = new SelectItem();
			departmentSelectItem.setAddUnknownValues(false);
			departmentField.setEditorValueMapFunction(new EditorValueMapFunction() {
				public Map getEditorValueMap(Map values, ListGridField field, ListGrid grid) {
					String division = (String) values.get("division");
					String[] divisions = departments.get(division);

					// convert divisions into ValueMap. In this case we simply create a Map with
					// same key -> value since
					// stored value is the same as user displayable value
					Map<Integer, String> valueMap = new HashMap<Integer, String>();
					for (int i = 0; i < divisions.length; i++) {
						String val = divisions[i];
						valueMap.put(i + 1, val);
					}
					return valueMap;
				}
			});
			departmentField.setEditorProperties(departmentSelectItem);
			
			Map<String, String> map = new LinkedHashMap<String, String>();
			map.put("2", "Charles Madigen");
			SelectItem projectsSelectItem = new SelectItem();
			projectsSelectItem.setTitle("Select:");
			projectsSelectItem.setName(TestDataSource.UNIQUE_ID_FIELD);
			projectsSelectItem.setTitleAlign(Alignment.LEFT);
			projectsSelectItem.setWrapTitle(false);
			projectsSelectItem.setOptionDataSource(dataSource);
			projectsSelectItem.setSortField(TestDataSource.NAME_FIELD);
			projectsSelectItem.setSeparateSpecialValues(true);
			projectsSelectItem.setSpecialValues(map);
			projectsSelectItem.setDisplayField(TestDataSource.NAME_FIELD);
			projectsSelectItem.setValueField(TestDataSource.UNIQUE_ID_FIELD);
			projectsSelectItem.setFetchMissingValues(false);
			projectsSelectItem.setDefaultToFirstOption(false);
			projectsSelectItem.setAlign(Alignment.LEFT);

			grid = new ListGrid() {
				protected Canvas getRollOverCanvas(Integer rowNum, Integer colNum) {
					SC.logWarn("Enters");
					if (rollOverCanvas == null) {
						rollOverCanvas = new HLayout(3);
						rollOverCanvas.setSnapTo("R");
						rollOverCanvas.setWidth(22);
						rollOverCanvas.setHeight(22);

						ImgButton editImg = new ImgButton();
						editImg.setShowDown(false);
						editImg.setShowRollOver(false);
						editImg.setLayoutAlign(Alignment.CENTER);
						editImg.setSrc("Details.png");
						editImg.setHeight(16);
						editImg.setWidth(16);
						editImg.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
							public void onClick(ClickEvent event) {
							}
						});

						rollOverCanvas.addMember(editImg);
					}
					return rollOverCanvas;
				}
			};
			grid.setWidth(500);
			grid.setHeight(500);
			grid.setCanEdit(true);
			grid.setEditByCell(true);
			grid.setDataSource(dataSource);
			grid.setAutoFetchData(true);
			grid.setFields(nameGridField, startDateField, divisionField, departmentField);
			grid.setShowRollOverCanvas(true);

			grid.addKeyPressHandler(new KeyPressHandler() {
				public void onKeyPress(KeyPressEvent event) {
					if (event.getKeyName().equals("Arrow_Up") && EventHandler.ctrlKeyDown()) {
						event.cancel();
						SC.say(EventHandler.getKey());
					}
				}
			});

			tileGrid = new TestTileGrid();
			tileGrid.setWidth(500);
			tileGrid.setHeight(500);
			tileGrid.setDataSource(dataSource);
			tileGrid.setAutoFetchData(true);

			Button button = new Button();
			button.setTitle("Update cache");
			button.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					dataSource.updateCacheTest();
				}
			});

			DynamicForm projectsDynamicForm = new DynamicForm();

			projectsDynamicForm.setItems(projectsSelectItem);
			this.setMembers(button, projectsDynamicForm, grid, tileGrid);
		}
	}

	public class TestTile extends SimpleTile {
		private Label nameField;
		private VLayout taskPanel;
		private VLayout mainLayout;

		public TestTile() {
			setHeight(1);
			setWidth("100%");
			setOverflow(Overflow.VISIBLE);

			nameField = new Label();
			nameField.setHeight(20);

			taskPanel = new VLayout();
			taskPanel.addMember(nameField);

			mainLayout = new VLayout();
			mainLayout.setHeight("1");
			mainLayout.setPadding(15);
			mainLayout.addMember(taskPanel);

			addChild(mainLayout);

			addMouseOverHandler(new MouseOverHandler() {
				@Override
				public void onMouseOver(MouseOverEvent event) {
					TestTileGrid tileGrid = (TestTileGrid) getTileGrid();
					// tileGrid.lastTileOver = (TestTile)tileGrid.getCurrentTile();
					// tileGrid.lastTileOver.setStyleName("simpleTileOver");
					SC.logWarn("over");

					tileGrid.getRollOverCanvas().placeNear(getAbsoluteLeft() + 10, getAbsoluteTop() + 10);
					tileGrid.getRollOverCanvas().show();
				}
			});

			addMouseOutHandler(new MouseOutHandler() {
				@Override
				public void onMouseOut(MouseOutEvent event) {
					SC.logWarn("out");
					Canvas target = EventHandler.getTarget();
					TestTileGrid tileGrid = (TestTileGrid) getTileGrid();
					SimpleTile currentTile = tileGrid.getCurrentTile();
					if (target == null || (target != tileGrid.getRollOverCanvas())
							&& (target.getParentCanvas() != tileGrid.getRollOverCanvas())) {
						tileGrid.getRollOverCanvas().hide();
						tileGrid.lastTileOver.setStyleName("simpleTile");
					} else {
						// TestTile.this.setStyleName("simpleTileOver");
						tileGrid.lastTileOver.setStyleName("simpleTileOver");
						event.cancel();
					}
				}
			});
		}

		public TestTile(Record record, Integer tileIndex) {
			this();
			nameField.setContents(record.getAttributeAsString(TestDataSource.NAME_FIELD));
		}

		public String getInnerHTML() {
			return "";
		}

		public String getDragTracker() {
			return "<pre>" + nameField.getTitle() + "</pre>";
		}
	}

	public class TestTileGrid extends TileGrid {
		private HLayout rollOverCanvas;
		public TestTile lastTileOver;

		public TestTileGrid() {
			setLayoutPolicy(TileLayoutPolicy.FLOW);
			setTilesPerLine(1);
			setCanReorderTiles(false);
			setHeight("100%");
			setWidth(250);
			setBorder("1px solid grey");
			setSelectionType(SelectionStyle.SINGLE);
			setShowAllRecords(true);
			setAnimateTileChange(true);
			setCanDragTilesOut(true);
			setCanAcceptDroppedRecords(true);
			setAddDropValues(true);
			setAutoFetchTextMatchStyle(TextMatchStyle.EXACT);
			setFields(new DetailViewerField(TestDataSource.NAME_FIELD));

			setTileConstructor(TestTile.class.getName());
			setCreateTileCustomizer(new CreateTileCustomizer() {
				@Override
				public Canvas createTile(Record record, Integer tileIndex) {
					return new TestTile(record, tileIndex);
				}
			});

			addMouseMoveHandler(new MouseMoveHandler() {
				@Override
				public void onMouseMove(MouseMoveEvent event) {
					SimpleTile tile = getCurrentTile();
					if (tile != null) {
						lastTileOver = (TestTile) tile;
					}
				}
			});
		}

		public Canvas getRollOverCanvas() {
			if (rollOverCanvas == null) {
				rollOverCanvas = new HLayout(3);
				rollOverCanvas.setSnapTo("R");
				rollOverCanvas.setWidth(22);
				rollOverCanvas.setHeight(22);

				ImgButton editImg = new ImgButton();
				editImg.setShowDown(false);
				editImg.setShowRollOver(false);
				editImg.setLayoutAlign(Alignment.CENTER);
				editImg.setSrc("Details.png");
				editImg.setHeight(16);
				editImg.setWidth(16);
				editImg.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
					public void onClick(ClickEvent event) {
					}
				});
				
				rollOverCanvas.addMember(editImg);
			}
			
			return rollOverCanvas;
		}
	}

	public class TestDataSource extends DataSource {

		private static final String DS_UNIQUE_ID = "_TestDataSource";

		public static final String UNIQUE_ID_FIELD = "uniqueIdField" + DS_UNIQUE_ID;
		public static final String NAME_FIELD = "nameField" + DS_UNIQUE_ID;
		public static final String START_DATE_FIELD = "startDateField" + DS_UNIQUE_ID;

		private TestDataSource() {

			DataSourceField uniqueId = new DataSourceField();
			uniqueId.setName(UNIQUE_ID_FIELD);
			uniqueId.setPrimaryKey(true);
			uniqueId.setHidden(true);
			uniqueId.setType(FieldType.INTEGER);

			DataSourceField name = new DataSourceField();
			name.setName(NAME_FIELD);

			DataSourceField startDate = new DataSourceField();
			startDate.setName(START_DATE_FIELD);
			startDate.setType(FieldType.DATE);

			ListGridRecord node1 = new ListGridRecord();
			node1.setAttribute(UNIQUE_ID_FIELD, 2l);
			node1.setAttribute(NAME_FIELD, "Charles Madigen");
			node1.setAttribute(START_DATE_FIELD, new Date());
			node1.setAttribute("division", "Marketing");
			node1.setAttribute("department", 1);

			ListGridRecord node2 = new ListGridRecord();
			node2.setAttribute(UNIQUE_ID_FIELD, 3l);
			node2.setAttribute(NAME_FIELD, "Rogine Leger");
			node2.setAttribute(START_DATE_FIELD, new Date(new Date().getTime() - 7 * 24 * 3600 * 1000));
			node2.setAttribute("division", "Marketing");
			node2.setAttribute("department", 1);

			ListGridRecord node3 = new ListGridRecord();
			node3.setAttribute(UNIQUE_ID_FIELD, 4l);
			node3.setAttribute(NAME_FIELD, "Gene Porter");
			node3.setAttribute(START_DATE_FIELD, new Date(new Date().getTime() + 7 * 24 * 3600 * 1000));
			node3.setAttribute("division", "Marketing");
			node3.setAttribute("department", 1);

			List<ListGridRecord> records = new LinkedList<ListGridRecord>();
			records.add(node1);
			records.add(node2);
			records.add(node3);
//			for (int i = 0; i < 21; i++) {
//				ListGridRecord node = new ListGridRecord();
//				node.setAttribute(UNIQUE_ID_FIELD, i + 10);
//				node.setAttribute(NAME_FIELD, "Charles Madigen" + i);
//				node.setAttribute(START_DATE_FIELD, new Date());
//				node.setAttribute("division", "Marketing");
//				node.setAttribute("department", 1);
//				records.add(node);
//			}

			this.setID(DS_UNIQUE_ID);
			this.setClientOnly(true);
			this.setFields(uniqueId, name, startDate);
			this.setCacheData(records.toArray(new ListGridRecord[0]));
		}

		public void updateCacheTest() {
			ListGridRecord node1 = new ListGridRecord();
			node1.setAttribute(UNIQUE_ID_FIELD, 2l);
			node1.setAttribute(NAME_FIELD, "Charles Madigen" + new Date().getTime());

			ListGridRecord node2 = new ListGridRecord();
			node2.setAttribute(UNIQUE_ID_FIELD, 3l);
			node2.setAttribute(NAME_FIELD, "Rogine Leger" + new Date().getTime());

			ListGridRecord node3 = new ListGridRecord();
			node3.setAttribute(UNIQUE_ID_FIELD, 4l);
			node3.setAttribute(NAME_FIELD, "Gene Porter" + new Date().getTime());

			DSResponse dsResponse = new DSResponse();
			dsResponse.setData(new ListGridRecord[] { node1, node2, node3 });
			dsResponse.setOperationType(DSOperationType.UPDATE);
			updateCaches(dsResponse);
		}
	}
}
