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

import java.util.logging.Logger;

import netjfwatcher.application.NetJFWatcherPlugin;
import netjfwatcher.engine.model.action.ActionBuilderAlarmList;
import netjfwatcher.engine.model.action.ActionBuilderEditorsPartClose;
import netjfwatcher.engine.model.action.ActionBuilderNodeList;
import netjfwatcher.engine.model.action.EngineStatus;
import netjfwatcher.engine.view.canvas.CanvasViewConfigFileParse;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.SubStatusLineManager;
import org.eclipse.jface.resource.ImageDescriptor;
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.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.Bundle;

/**
 * ノードMapを表示するViewクラスです。
 * 
 * @author Yoshimasa Matsumoto
 * @version 1.0
 */
public class NodeMapDrawView extends ViewPart {
	/* ロギング */
	private static Logger logger;

	/* Node Map View size */
	private int[] nodeMapViewSize = new int[2];

	/* 配色Color定義 */
	private Color whiteColor = new Color(null, 255, 255, 255);

	/* 配色Color定義 */
	private Color blackColor = new Color(null, 0, 0, 0);

	/* 配色Color定義 */
	private Color redColor = new Color(null, 255, 0, 0);

	/* Display */
	private Display display;

	/* ノードMap View上のマウスリスナー */
	private NodeMapDrawViewMouseListener mouseListener;

	/* ノードMap Canvas */
	private Canvas canvas;

	/* GC */
	private GC gc;

	/* ステータスラインマネージャ */
	private SubStatusLineManager statusLineManager;

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

	/* ノードリストアクション */
	private NodeListAction nodeListAction = new NodeListAction();

	/* EditorsPartに表示するアクション */
	private ActionBuilderEditorsPartClose actionBuilderEditorPart = new ActionBuilderEditorsPartClose();

	/* アラームアクション */
	private ActionBuilderAlarmList actionBuilderAlarm = new ActionBuilderAlarmList();

	/**
	 * ノードMap Viewクラスインスタンスを生成します。
	 * 
	 */
	public NodeMapDrawView() {
		logger = Logger.getLogger(this.getClass().getName());
	}

	/**
	 * ビューが生成されたときにまず実行されメソッドです。
	 * 
	 * @param parent
	 *            Composite
	 */
	public void createPartControl(final Composite parent) {
		setCanvasSize();
		/*
		 * 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();
		ScrolledComposite scrollComposite = new ScrolledComposite(parent,
				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);

		statusLineManager = (SubStatusLineManager) (getViewSite()
				.getActionBars().getStatusLineManager());

		mouseListener = new NodeMapDrawViewMouseListener(scrollComposite,
				display, parent, canvas, gc, statusLineManager, false);
		mouseListener.getPopMenu().setPopUpMenu(parent);

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

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

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

		setToolBarActions();
	}

	protected void setCanvasSize() {
		nodeMapViewSize[0] = CanvasViewConfigFileParse.getInstance()
				.getNodeMapWidth();
		nodeMapViewSize[1] = CanvasViewConfigFileParse.getInstance()
				.getNodeMapHeight();
	}

	/**
	 * ToolBarアクションの初期化を行います。
	 * 
	 */
	protected void setToolBarActions() {
		IToolBarManager toolBarManager = getViewSite().getActionBars()
				.getToolBarManager();

		/* Node Map更新アクション */
		toolBarManager.add(new ActionLoadNodeMapView());

		/* Node監視情報Import */
		toolBarManager.add(nodeListAction.getActionImportNodeListFile());

		/* Node監視情報Export */
		toolBarManager.add(nodeListAction.getActionExportNodeListFile());

		/* 全ノードAlarm表示アクション */
		toolBarManager.add(actionBuilderAlarm
				.getActionShowAllNodeAlarmListTable());

		/* Editor part closeアクション */
		toolBarManager.add(actionBuilderEditorPart.actionCloseAllEditors());
	}

	/*
	 * (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() {
	}

	/*
	 * ノードListテーブルのアクションを実装します。
	 * 
	 * @author Yoshimasa Matsumoto
	 * 
	 * @version 1.0
	 */
	protected class NodeListAction extends ActionBuilderNodeList {
	}

	/**
	 * ノードMap Viewのアクション抽象クラスです。
	 * 
	 * @author Yoshimasa Matsumoto
	 * @version 1.0
	 */
	public abstract class AbstractNodeMapAction extends Action {
		/**
		 * Node Listを読み込んでテーブル表示するアクションのアイコン ImageDescriptorを返します。
		 * 
		 * @return Node Listを読み込んでテーブル表示するアクション のアイコンImageDescriptor
		 */
		public ImageDescriptor getImageDescriptor() {
			return ImageDescriptor.createFromURL(bundle
					.getEntry("icons/reload.gif"));
		}

		/**
		 * Node Listを読み込んでテーブル表示するアクションのTextを 返します。
		 * 
		 * @return Node Listを読み込んでテーブル表示するアクション のText
		 */
		public String getText() {
			return "Node Map Load";
		}

		/**
		 * Node Listを読み込んでテーブル表示するアクションのToolTipTextを返します。
		 * 
		 * @return ToolTipText
		 */
		public String getToolTipText() {
			return "Node Map Load";
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		public final void run() {
			doTask();
		}

		/**
		 * アクションで実行するタスクです。
		 * 
		 */
		protected abstract void doTask();
	}

	/**
	 * Node Map情報を読み込んでMap表示するアクションクラスです。
	 */
	public class ActionLoadNodeMapView extends AbstractNodeMapAction {
		/**
		 * Node Map表示を更新します。
		 * 
		 */
		protected void doTask() {
			mouseListener.getPopMenu().loadNodeMap();
		}
	}
}
