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

import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Logger;

import netjfwatcher.common.view.MenuPreference;
import netjfwatcher.engine.command.control.CommandMappingTableResource;
import netjfwatcher.engine.nodemaneger.map.NodeMapInfo;
import netjfwatcher.engine.nodemaneger.map.NodeMapMenuNodeAlarm;
import netjfwatcher.engine.nodemaneger.map.NodeMapMenuNodeConfig;
import netjfwatcher.engine.nodemaneger.map.NodeMapMenuNodeOperation;
import netjfwatcher.engine.nodemaneger.map.NodeMapMenuNodeSnmp;
import netjfwatcher.engine.nodemaneger.map.NodeMapMenuNodeSnmpStatisticsSet;
import netjfwatcher.engine.resourceconfig.ClientEngineInfo;
import netjfwatcher.engine.socket.ConnectionNodeControl;
import netjfwatcher.engine.socket.ConnectionNodeInformation;
import netjfwatcher.engine.socket.ConnectionNodeMapLink;
import netjfwatcher.engine.socket.EngineConnectException;
import netjfwatcher.engine.socket.info.NodeInformation;
import netjfwatcher.engine.view.editorpart.ping.NodePingMenu;
import netjfwatcher.engine.view.editorpart.snmp.NodeSnmpStatisticsMenu;

import org.eclipse.jface.action.SubStatusLineManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

/**
 * ノードMap ViewのCanvas上のPopUpメニューを実装するクラスです。
 * 
 * @author Yoshimasa Matsumoto
 * @version 1.0
 */
public class NodeMapDrawViewPopUpMenuSocket extends NodeMapDrawViewPopUpMenu {
	/* ロギング */
	private static Logger logger;

	/**
	 * ノードMap ViewのCanvas上のPopUpメニューを実装するクラスインスタンスを 生成します、
	 * 
	 * @param display
	 *            Display
	 * @param canvas
	 *            Canvas
	 * @param mapDraw
	 *            ノードMap描画クラスインスタンス
	 * @param mouseListener
	 *            マウスリスナークラスインスタンス
	 * @param statusLineManager
	 *            ステータスラインマネージャ
	 */
	public NodeMapDrawViewPopUpMenuSocket(Display display, Canvas canvas,
			NodeMapDrawViewDraw mapDraw,
			NodeMapDrawViewMouseListener mouseListener,
			SubStatusLineManager statusLineManager) {
		super(display, canvas, mapDraw, mouseListener, statusLineManager);
		logger = Logger.getLogger(this.getClass().getName());
	}

	/**
	 * Popupメニューをセットします。
	 * 
	 * @param parent
	 *            Composite
	 */
	public void setPopUpMenu(Composite parent) {

		/* popUpメニューセット */
		popUpMenu = new Menu(parent.getShell(), SWT.POP_UP);
		canvas.setMenu(popUpMenu);

		MenuItem menuItemLoad = new MenuItem(popUpMenu, SWT.PUSH);
		menuItemLoad.setText(LOAD_MENU);

		menuItemLoad.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {

				loadNodeMap();
			}
		});

		/*
		 * ノードMap Save処理
		 */
		MenuItem menuItemSave = new MenuItem(popUpMenu, SWT.PUSH);
		menuItemSave.setText(SAVE_MENU);

		/*
		 * ノードMap popupメニューでのSave選択
		 */
		menuItemSave.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				String engineAddress = ClientEngineInfo
						.getClientEngineInfoInstance().getEngineAddress();

				for (int i = 0; i < nodeMapNodeInfoList.size(); i++) {
					NodeMapInfo nodeMapInfo = (NodeMapInfo) nodeMapNodeInfoList
							.get(i);
					NodeInformation nodeInfo = nodeMapInfo.getNodeInfo();

					ConnectionNodeControl threadstop = new ConnectionNodeControl(
							engineAddress);

					try {
						threadstop
								.requestThread(
										nodeInfo.getIpaddress(),
										CommandMappingTableResource.THREAD_RESTART_COMMAND_ID,
										nodeInfo);
					} catch (EngineConnectException e1) {
						Shell shell = new Shell();
						MessageDialog.openError(shell,
								"Node List import error", e1.getMessage());
						logger.warning("Node List import error"
								+ e1.getMessage());
						shell.dispose();
						e1.printStackTrace();
					} catch (IOException e1) {
						Shell shell = new Shell();
						MessageDialog.openError(shell,
								"Node List import error", e1.getMessage());
						logger.warning("Node List import error"
								+ e1.getMessage());
						shell.dispose();
						e1.printStackTrace();
					}
				}

				if (nodMapLinkInformationList == null) {
					return;
				}

				ConnectionNodeMapLink connectNodeInfo = new ConnectionNodeMapLink(
						engineAddress);

				try {
					nodMapLinkInformationList = connectNodeInfo
							.updateNodeMapInformation(nodMapLinkInformationList);
				} catch (EngineConnectException e1) {
					Shell shell = new Shell();
					MessageDialog.openError(shell, "Node List import error", e1
							.getMessage());
					logger.warning("Node List import error" + e1.getMessage());
					shell.dispose();
					e1.printStackTrace();
				} catch (IOException e1) {
					Shell shell = new Shell();
					MessageDialog.openError(shell, "Node List import error", e1
							.getMessage());
					logger.warning("Node List import error" + e1.getMessage());
					shell.dispose();
					e1.printStackTrace();
				}
			}
		});

		/*
		 * Linkメニュー生成
		 */
		MenuItem menuItemLink = new MenuItem(popUpMenu, SWT.CHECK);
		menuItemLink.setText(LINK_MENU);

		if (mouseListener.isLineSelected()) {
			menuItemLink.setSelection(true);
		} else {
			menuItemLink.setSelection(false);
		}

		/*
		 * Linkメニュー選択処理
		 */
		menuItemLink.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				/*
				 * Linkフラグ(Link描画モードかノードIcon移動 モード)を反転
				 */
				if (mouseListener.isLineSelected()) {
					mouseListener.setLineSelected(false);
				} else {
					mouseListener.setLineSelected(true);
				}
			}
		});
	}

	/**
	 * ノード個別メニューとして、ノード選択時にPopupメニューに ノード選択メニューを追加します。
	 * 
	 * @param nodeI
	 *            ノード監視情報
	 */
	protected void setNodeMenu(final NodeInformation nodeI, boolean isNodeMenu) {
		if (isNodeMenu) {
			nodeViewMenuItem = new MenuItem(popUpMenu, SWT.PUSH);
			nodeViewMenuItem.setText(MenuPreference.NODE_CONFIG_VIEW);

			NodeMapMenuNodeConfig nodeConfig = new NodeMapMenuNodeConfig(nodeI,
					true);
			nodeViewMenuItem.addSelectionListener(nodeConfig);

			nodeAlarmMenuItem = new MenuItem(popUpMenu, SWT.PUSH);
			nodeAlarmMenuItem.setText(MenuPreference.NODE_ALARM_VIEW);

			NodeMapMenuNodeAlarm nodeAlarm = new NodeMapMenuNodeAlarm(nodeI,
					true);
			nodeAlarmMenuItem.addSelectionListener(nodeAlarm);

			nodeSnmpMenuItem = new MenuItem(popUpMenu, SWT.PUSH);
			nodeSnmpMenuItem.setText(MenuPreference.NODE_SNMP_VIEW);

			NodeMapMenuNodeSnmp nodeSnmp = new NodeMapMenuNodeSnmp(nodeI, true);
			nodeSnmpMenuItem.addSelectionListener(nodeSnmp);

			NodePingMenu menuPing = new NodePingMenu();
			menuPing.createPingMenu(popUpMenu, nodeI, true);

			NodeSnmpStatisticsMenu menuSnmpStatistics = new NodeSnmpStatisticsMenu();
			menuSnmpStatistics.createSnmpStatisticsMenu(popUpMenu, nodeI, true);

			nodeSnmpStatisticsSetMenuItem = new MenuItem(popUpMenu, SWT.PUSH);
			nodeSnmpStatisticsSetMenuItem
					.setText(MenuPreference.NODE_SNMP_STATISTICS_SET);

			NodeMapMenuNodeSnmpStatisticsSet nodeSnmpStatisticsSet = new NodeMapMenuNodeSnmpStatisticsSet(
					nodeI, true);
			nodeSnmpStatisticsSetMenuItem
					.addSelectionListener(nodeSnmpStatisticsSet);
		}
		/* ノード構成定義メニュー */
		nodeViewMenuItem = new MenuItem(popUpMenu, SWT.PUSH);
		nodeViewMenuItem.setText(MenuPreference.NODE_OPERATION_VIEW);

		NodeMapMenuNodeOperation nodeOperaqtion = new NodeMapMenuNodeOperation(
				nodeI, false);
		nodeViewMenuItem.addSelectionListener(nodeOperaqtion);
	}

	/**
	 * ノードMap情報リストをSocket経由でエンジン部から取得します。
	 * 
	 * @param isNodeInfo
	 *            ノードMap Link情報をSocket経由でエンジン部から取得するか否かフラグ
	 * @return nodeList ノードMap情報リスト
	 */
	protected ArrayList getNodeInfoListMapView(boolean isNodeInfo) {
		if (!isNodeInfo) {
			return new ArrayList();
		}

		ArrayList nodeList = null;
		String engineAddress = ClientEngineInfo.getClientEngineInfoInstance()
				.getEngineAddress();

		try {
			ConnectionNodeInformation connectNodeInfo = new ConnectionNodeInformation(
					engineAddress);
			nodeList = connectNodeInfo.getNodeInformationList(null, null);

			if (nodeList.size() == 0) {
				return nodeList;
			}
		} catch (EngineConnectException e) {
			Shell shell = new Shell();
			MessageDialog.openError(shell, "Node List import error", e
					.getMessage()
					+ "Engine = " + engineAddress);
			logger.warning("Node List import error" + e.getMessage()
					+ "Engine = " + engineAddress);
			shell.dispose();
			e.printStackTrace();
		} catch (IOException e) {
			Shell shell = new Shell();
			MessageDialog.openError(shell, "Node List import error", e
					.getMessage()
					+ "Engine = " + engineAddress);
			logger.warning("Node List import error" + e.getMessage()
					+ "Engine = " + engineAddress);
			shell.dispose();
			e.printStackTrace();
		}

		return nodeList;
	}

	/*
	 * ノードMap Link情報をSocket経由でエンジン部から取得します。
	 * 
	 * @param isNodeMap ノードMap Link情報をSocket経由でエンジン部から取得するか否かフラグ
	 */
	private void getNodeMapLink(boolean isNodeMap) {
		if (!isNodeMap) {
			return;
		}

		String engineAddress = ClientEngineInfo.getClientEngineInfoInstance()
				.getEngineAddress();

		try {
			ConnectionNodeMapLink connectNodeInfo = new ConnectionNodeMapLink(
					engineAddress);
			nodMapLinkInformationList = connectNodeInfo.getNodeMapInformation();
		} catch (EngineConnectException e) {
			Shell shell = new Shell();
			MessageDialog.openError(shell, "Node List import error", e
					.getMessage()
					+ "Engine = " + engineAddress);
			logger.warning("Node List import error" + e.getMessage()
					+ "Engine = " + engineAddress);
			shell.dispose();
			e.printStackTrace();
		} catch (IOException e) {
			Shell shell = new Shell();
			MessageDialog.openError(shell, "Node List import error", e
					.getMessage()
					+ "Engine = " + engineAddress);
			logger.warning("Node List import error" + e.getMessage()
					+ "Engine = " + engineAddress);
			shell.dispose();
			e.printStackTrace();
		}
	}

	/**
	 * ノードMap View情報をロードして描画します。
	 * 
	 */
	public void loadNodeMap() {
		getNodeMapLink(true);

		ArrayList nodeList = getNodeInfoListMapView(true);
		createNodeMapInfo(nodeList);

		mapDraw.redraw(nodeMapNodeInfoList, nodMapLinkInformationList);

		setStatusLine();
	}
}
