/* $Id: GlobalViewPanel.java 373 2011-10-01 16:30:41Z shayashi $ */
/*
 * 作成日: 2006/06/02
 *
 */
package smart_gs.reasoning_web.swingui;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

import reasoning_web.logical.Connection;
import reasoning_web.logical.ResourcePointer;
import reasoning_web.logical.inter_face.RWElement;
import smart_gs.logical.Preference;
import smart_gs.reasoning_web.logical.GSConnection;
import smart_gs.reasoning_web.logical.GSResourcePointer;
import smart_gs.reasoning_web.logical.GS_RWElement;
import smart_gs.reasoning_web.logical.GS_RWRepository;
import smart_gs.reasoning_web.swingui.mouse_listener.GlobalViewMouseListener;
import smart_gs.reasoning_web.swingui.view.View;
import smart_gs.util.CanonicalPathString;

/**
 * @author kazuaki kobayashi
 * 
 * 
 */
@SuppressWarnings("serial")
public class GlobalViewPanel extends JPanel implements MouseListener,
		MouseMotionListener {
	// 2007/11/1 kazuhiro kobayashi
	private int maxX = 0;
	private int maxY = 0;

	private static GlobalViewPanel singleton = new GlobalViewPanel();
	private GlobalViewMouseListener listener = new GlobalViewMouseListener();

	// 2007/11/13 kazuhiro kobayshi
	private BufferedImage readImage = null;
	private float visibility = 1.0f;

	private GlobalViewPanel() {

		// *******************2007/11/13 kazuhiro kobayashi この部分を削除！******
		// 2007/11/13 kazuhiro kobayashi この部分を削除！
		// 2007/11/1 kazuhiro koabayashi
		// if (this.maxX != 0 || this.maxY != 0) {
		// this.setPreferredSize(new Dimension(this.maxX, this.maxY));
		// }
		// *******************************************************************

		if(!Preference.getInstance().getRWBackgroundFilePathString().equals("")){
			//2007/12/8 kazuhiro kobayshi
			BufferedImage bufferedImage = null;
			try{
				bufferedImage = ImageIO.read(new File(Preference.getInstance().getRWBackgroundFilePathString()));
			}catch(Exception e){}
			// 読み込みに失敗した場合は、設定しない。 NorthGrid 20090713
			if(bufferedImage != null){
				this.setReadImage(bufferedImage);
			}
		}
		
		
		this.setBackground(Color.white);

		this.setOpaque(false);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
	}

	public static GlobalViewPanel getInstance() {
		return singleton;
	}

	public GS_RWElement getSelectedElement() {
		return this.listener.getSelectedElement();
	}

	// 2007/10/30 kazuhiro kobayashi
	public void setSelectedElement(GS_RWElement element) {
		this.listener.setSelectedElement(element);
	}

	public RWElement getElement(Point point) {
		List<ResourcePointer> elements = GS_RWRepository.getInstance()
				.getResourcePointers();
		for (int i = 0; i < elements.size(); i++) {
			View view = ((GSResourcePointer) elements.get(i)).getView();
			if (view.contains(point)) {
				return elements.get(i).getRwElement();
			}
		}
		List<Connection> connections = GS_RWRepository.getInstance()
				.getConnections();
		for (int i = 0; i < connections.size(); i++) {
			View view = ((GSConnection) connections.get(i)).getView();
			if (view.contains(point)) {
				return connections.get(i);
			}
		}
		return null;
	}

	// 2007/10/23 kazuhiro kobayashi
	public ResourcePointer getResourcePointer(Point point) {
		List<ResourcePointer> elements = GS_RWRepository.getInstance()
				.getResourcePointers();
		for (int i = 0; i < elements.size(); i++) {
			View view = ((GSResourcePointer) elements.get(i)).getView();
			if (view.contains(point)) {
				return elements.get(i);
			}
		}
		return null;
	}

	// 2007/11/1 kazuhiro koabayshi
	public Connection getConnection(Point point) {
		List<Connection> connections = GS_RWRepository.getInstance()
				.getConnections();
		for (int i = 0; i < connections.size(); i++) {
			View view = ((GSConnection) connections.get(i)).getView();
			if (view.contains(point)) {
				return connections.get(i);
			}
		}
		return null;
	}

	public View getView(Point point) {
		List<ResourcePointer> elements = GS_RWRepository.getInstance()
				.getResourcePointers();
		for (int i = 0; i < elements.size(); i++) {
			View view = ((GSResourcePointer) elements.get(i)).getView();
			if (view.contains(point)) {
				return view;
			}
		}
		List<Connection> connections = GS_RWRepository.getInstance()
				.getConnections();
		for (int i = 0; i < connections.size(); i++) {
			View view = ((GSConnection) connections.get(i)).getView();
			if (view.contains(point)) {
				return view;
			}
		}
		return null;
	}

	public void paint(Graphics g) {
		super.paint(g);
		Iterator<Connection> it = GS_RWRepository.getInstance()
				.getConnections().iterator();
		while (it.hasNext()) {
			View view = ((GSConnection) it.next()).getView();
			view.drawShape((Graphics2D) g);
			// view.drawTranslucentShape((Graphics2D)g);
		}
		List<ResourcePointer> pointers = GS_RWRepository.getInstance()
				.getResourcePointers();
		for (int i = 0; i < pointers.size(); i++) {
			View view = ((GSResourcePointer) pointers.get(i)).getView();
			// 2007/11/1 kazuhiro kobayashi
			this.setMaxPanelSize(view);
			view.drawShape((Graphics2D) g);
			// view.drawTranslucentShape((Graphics2D)g);
		}
		this.stretchPanel(new Dimension(this.maxX, this.maxY));

	}

	public void mouseDragged(MouseEvent e) {
		this.listener.mouseDragged(e);
		this.repaint();
	}

	public void mouseMoved(MouseEvent e) {
		this.listener.mouseMoved(e);
		this.repaint();

	}

	public void mouseClicked(MouseEvent e) {
		this.listener.mouseClicked(e);
		this.repaint();
	}

	public void mouseEntered(MouseEvent e) {
		this.listener.mouseEntered(e);
		this.repaint();
	}

	public void mouseExited(MouseEvent e) {
		this.listener.mouseExited(e);
		this.repaint();
	}

	public void mousePressed(MouseEvent e) {
		this.listener.mousePressed(e);
		this.repaint();
	}

	public void mouseReleased(MouseEvent e) {
		this.listener.mouseReleased(e);
		this.repaint();
	}

	// 2007/11/1 kazuhiro kobayashi
	public void stretchPanel(Dimension d) {
		GlobalViewPanel.getInstance().setPreferredSize(d);
		GlobalViewPanel.getInstance().invalidate();
		GlobalViewPanel.getInstance().getParent().validate();
	}

	public void setGlobalViewPanelSize(Point2D point) {
		int x = (int) point.getX();
		int y = (int) point.getY();
		int globalx = GlobalViewPanel.getInstance().getWidth();
		int globaly = GlobalViewPanel.getInstance().getHeight();
		Dimension d;
		if (x >= globalx && y < globaly) {
			d = new Dimension(x + 20, globaly);
			GlobalViewPanel.getInstance().stretchPanel(d);
		} else if (x < globalx && y >= globaly) {
			d = new Dimension(globalx, y + 20);
			GlobalViewPanel.getInstance().stretchPanel(d);
		} else if (x >= globalx && y >= globaly) {
			d = new Dimension(x + 20, y + 20);
			GlobalViewPanel.getInstance().stretchPanel(d);
		}
	}

	// 2007/11/20 kazuhiro kobayashi
	public void setMaxPanelSize(View view) {
		int x = (int) view.getRectangle().getMaxX();
		int y = (int) view.getRectangle().getMaxY();
		if (x > this.maxX) {
			this.maxX = x + 200;
		}
		if (y > this.maxY) {
			this.maxY = y + 100;
		}
	}

	// 2007/11/13 kazuhiro kobayashi
	@Override
	public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
				this.visibility));
		g2.drawImage(readImage, 0, 0, null);

		super.paintComponent(g2);
	}

	//20090422 North Grid
	public void setBackground(File file) {
		try{
			this.setReadImage(ImageIO.read(file));
			GS_RWRepository.getInstance().setBackgroundFilePath(CanonicalPathString.get(file));
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public void setReadImage(BufferedImage image) {
		this.readImage = image;
		if (readImage != null) {
			// 2007/11/24 kazuhiro kobayashi
			if (this.maxX < readImage.getWidth()) {
				this.maxX = readImage.getWidth();
			}
			if (this.maxY < readImage.getHeight()) {
				this.maxY = readImage.getHeight();
			}
			;
		}
		this.repaint();
	}

	public void setVisibility(float v) {
		this.visibility = v;
		this.repaint();
	}

}
