/*
 * Created on 2007/03/12
 *
 *
 * Copyright(c) 2007 Yoshimasa Matsumoto
 */
package netjfwatcher.nodemap.gui.icon;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.logging.Logger;

import netjfwatcher.application.NetJFWatcherPlugin;
import netjfwatcher.engine.model.action.MediaResource;
import netjfwatcher.engine.nodemaneger.map.NodeMapInfo;
import netjfwatcher.engine.socket.info.NodeInformation;
import netjfwatcher.engine.view.editorpart.node.EditorNodeOperationInitialData;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.Bundle;

public class NodeIconView extends ViewPart {
	/* ロギング */
	private static Logger logger;

	private int[] nodeMapViewSize = new int[2];

	private Color whiteColor = new Color(null, 255, 255, 255);

	private Color blackColor = new Color(null, 0, 0, 0);

	private Color redColor = new Color(null, 255, 0, 0);

	private static final int TEXT_WIDTH1 = 150;

	public static final int NODE_ICON_X = 20;

	public static final int NODE_ICON_Y = 20;

	private Display display;

	private NodeMapInfo nodeMapInfo;

	private Combo nodeKindCombo;

	private NodeIconViewMouseListener mouseListener;

	private Canvas canvas;

	private GC gc;

	/* ノード種別に対応したノードIcon Imageを格納するMap */
	private HashMap nodeIconImageMap = new HashMap();

	/* 画像を入手するためのPluginのResource bundle */
	private Bundle bundle = NetJFWatcherPlugin.getInstance().getBundle();

	public NodeIconView() {
		logger = Logger.getLogger(this.getClass().getName());
	}

	public void createPartControl(final Composite parent) {

		/*
		 * Colorオブジェクトが破棄されている場合は再セット
		 */
		if ((whiteColor == null) || whiteColor.isDisposed()) {
			whiteColor = new Color(null, 255, 255, 255);
		}

		if ((blackColor == null) || blackColor.isDisposed()) {
			blackColor = new Color(null, 0, 0, 0);
		}

		if ((redColor == null) || redColor.isDisposed()) {
			redColor = new Color(null, 255, 0, 0);
		}

		display = parent.getDisplay();

		GridLayout gridLayout2 = new GridLayout(1, false);
		Composite composite2 = new Composite(parent, SWT.NONE);
		composite2.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_FILL));
		composite2.setLayout(gridLayout2);

		/* ノード種別ComboBoxセット */
		setNodeKind(composite2);

		GridData gridData = new GridData();
		gridData.horizontalSpan = 1;
		gridData.verticalSpan = 1;
		gridData.widthHint = TEXT_WIDTH1;
		nodeKindCombo.setLayoutData(gridData);
		nodeKindCombo.setVisibleItemCount(15);

		nodeMapInfo = new NodeMapInfo();
		createNodeIcon();
		setCanvasSize();

		ScrolledComposite scrollComposite = new ScrolledComposite(composite2,
				SWT.H_SCROLL | SWT.V_SCROLL);

		GridLayout layout = new GridLayout(1, true);
		scrollComposite.setLayout(layout);

		canvas = new Canvas(scrollComposite, SWT.NULL);

		gc = new GC(canvas);

		scrollComposite.setBackground(whiteColor);
		gc.setBackground(scrollComposite.getBackground());
		scrollComposite.setContent(canvas);
		scrollComposite.setMinSize(nodeMapViewSize[0], nodeMapViewSize[1]);
		scrollComposite.setExpandHorizontal(true);
		scrollComposite.setExpandVertical(true);

		mouseListener = new NodeIconViewMouseListener(canvas, gc, false,
				nodeMapInfo);

		canvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				mouseListener.redraw();
			}
		});
		scrollComposite.addMouseListener(mouseListener);

		/*
		 * Canvas mouseリスナーセット
		 */
		canvas.addMouseListener(mouseListener);

		/*
		 * ノード移動またはLink描画処理
		 */
		canvas.addMouseMoveListener(mouseListener);

	}

	protected void setCanvasSize() {
		nodeMapViewSize[0] = NodeIconView.NODE_ICON_X + nodeMapInfo.getWidth()
				+ NodeIconView.NODE_ICON_X;
		nodeMapViewSize[1] = NodeIconView.NODE_ICON_Y + nodeMapInfo.getHeight()
				+ NodeIconView.NODE_ICON_Y;
	}

	private void setNodeKind(Composite composite2) {

		nodeKindCombo = new Combo(composite2, SWT.DROP_DOWN | SWT.READ_ONLY);
		HashMap nodeIconMap = MediaResource.getInstance().getIconDataList();
		Iterator it;

		for (it = nodeIconMap.keySet().iterator(); it.hasNext();) {
			String key = (String) it.next();
			nodeKindCombo.add(key);
		}

		nodeKindCombo.select(0);

		nodeKindCombo.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				int nodeKindSelectIndex = nodeKindCombo.getSelectionIndex();
				if (nodeKindSelectIndex < 0) {
					return;
				}

				createNodeIcon();

				mouseListener.getMapDraw().drawNode(nodeMapInfo);
			}
		});
	}

	private void createNodeIcon() {

		int pointX = NODE_ICON_X;
		int pointY = NODE_ICON_Y;
		String nodeKind = nodeKindCombo.getText();
		Image nodeImage = createNodeIconImage(nodeKind);

		nodeMapInfo.setNodeIconImage(nodeImage);
		nodeMapInfo.setX(pointX);
		nodeMapInfo.setY(pointY);
		nodeMapInfo.setNodeInfo(setTextDefaultNodeInfo(nodeKind));
		nodeMapInfo.setHeight(nodeImage.getBounds().height);
		nodeMapInfo.setWidth(nodeImage.getBounds().width);
	}

	private NodeInformation setTextDefaultNodeInfo(String nodeKind) {

		NodeInformation nodeInfo = new NodeInformation();
		nodeInfo.setNodename("");
		nodeInfo.setIpaddress("");
		nodeInfo.setNodeKind(nodeKind);

		nodeInfo.setGroup(EditorNodeOperationInitialData.INITIAL_NODE_GROUP);
		nodeInfo
				.setPingPeriod(EditorNodeOperationInitialData.INITIAL_NODE_PING_PERIOD);
		nodeInfo
				.setPingThreshold(EditorNodeOperationInitialData.INITIAL_NODE_PING_THRESHOLD);
		nodeInfo
				.setSnmpPeriod(EditorNodeOperationInitialData.INITIAL_NODE_SNMP_PERIOD);
		nodeInfo
				.setRoCommunity(EditorNodeOperationInitialData.INITIAL_NODE_SNMP_ROCOMMUNITY);
		nodeInfo
				.setRwCommunity(EditorNodeOperationInitialData.INITIAL_NODE_SNMP_RWCOMMUNITY);
		nodeInfo
				.setHttpUrl(EditorNodeOperationInitialData.INITIAL_NODE_HTTP_URL);
		nodeInfo
				.setHttpPort(EditorNodeOperationInitialData.INITIAL_NODE_HTTP_PORT);
		nodeInfo
				.setHttpPeriod(EditorNodeOperationInitialData.INITIAL_NODE_HTTP_PERIOD);
		nodeInfo
				.setHttpTimeout(EditorNodeOperationInitialData.INITIAL_NODE_HTTP_TIMEOUT);
		nodeInfo
				.setPopPeriod(EditorNodeOperationInitialData.INITIAL_NODE_POP_PERIOD);
		nodeInfo
				.setPopPort(EditorNodeOperationInitialData.INITIAL_NODE_POP_PORT);
		nodeInfo
				.setPopTimeout(EditorNodeOperationInitialData.INITIAL_NODE_POP_TIMEOUT);
		nodeInfo
				.setSmtpPeriod(EditorNodeOperationInitialData.INITIAL_NODE_SMTP_PERIOD);
		nodeInfo
				.setSmtpPort(EditorNodeOperationInitialData.INITIAL_NODE_SMTP_PORT);
		nodeInfo
				.setSmtpTimeout(EditorNodeOperationInitialData.INITIAL_NODE_SMTP_TIMEOUT);
		nodeInfo
				.setSmtpCheckPort(EditorNodeOperationInitialData.INITIAL_NODE_POP_PORT);
		nodeInfo
				.setSmtpCheckTimeout(EditorNodeOperationInitialData.INITIAL_NODE_POP_TIMEOUT);

		return nodeInfo;
	}

	private Image createNodeIconImage(String nodeKind) {
		/*
		 * ノード種別に対応したノードIconイメージファイルを 記述したXMLファイルからListを生成し、ノードIcon イメージファイル名を取得
		 */
		String nodeIconFileName = MediaResource.getInstance()
				.getNodeIconFullFileName(nodeKind);
		Image nodeIconImage = null;

		if (!nodeIconImageMap.containsKey(nodeIconFileName)) {
			URL url = null;
			url = bundle.getEntry(nodeIconFileName);

			if (url == null) {
				/* Iconリソースファイルが見つからない場合ロギング採取 */
				logger.severe("Not found icon file : " + nodeIconFileName);
			} else {
				try {
					/* ノードIconイメージ生成 */
					nodeIconImage = new Image(display, url.openStream());

					/* ノードIconイメージをMapに格納 */
					nodeIconImageMap.put(nodeIconFileName, nodeIconImage);
				} catch (IOException e) {
					logger.warning("Abort create image " + e.getMessage()
							+ " for " + nodeIconFileName);
					e.printStackTrace();
				}
			}
		} else {
			nodeIconImage = (Image) nodeIconImageMap.get(nodeIconFileName);
		}

		return nodeIconImage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#finalize()
	 */
	protected void finalize() throws Throwable {
		super.finalize();

		if (whiteColor != null) {
			whiteColor.dispose();
		}

		if (blackColor != null) {
			blackColor.dispose();
		}

		if (redColor != null) {
			redColor.dispose();
		}

		if (gc != null) {
			gc.dispose();
		}
	}

	/**
	 * フォーカスがセットされた時の処理です。
	 * 
	 */
	public void setFocus() {
	}

}
