/* $Id: Region.java 475 2011-12-02 08:46:54Z ohura $ */
package smart_gs.logical;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import java.util.List;

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



import reasoning_web.logical.RWRepository;
import reasoning_web.logical.ResourcePointer;
import reasoning_web.logical.inter_face.NoWayToShowException;
import smart_gs.GSConstants;
import smart_gs.drawing_tool.SpreadCanvas;
import smart_gs.drawing_tool.view.View;
import smart_gs.logical.region.AnchorRegion;
import smart_gs.logical.region.BookmarkRegion;
import smart_gs.logical.region.MarkerRegion;
import smart_gs.logical.region.MemoPadRegion;
import smart_gs.logical.region.PolygonRegion;
import smart_gs.logical.region.RectangleRegion;
import smart_gs.logical.visitor.ShowResourceVisitor;
import smart_gs.logical.visitor.Visitor;
import smart_gs.menu.action.SpreadJumpAction;
import smart_gs.menu.action.SpreadOpenAction;
import smart_gs.reasoning_web.logical.GS_RWRepository;
import smart_gs.reasoning_web.swingui.elementViewPanelListener;
import smart_gs.smleditor.swingui.GSEditor;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.util.ImageCropper;


public class Region extends GSResource implements Markup{

	protected Spread spread;
	protected View view;
	protected String baseURI;
	public List<Point2D> points;
	
	private boolean isLineSegment;
	
	private String timeZone;
	
	/*
	 * region自身が　どのsheetにいるのかは知らないほうがいいのかもしれない
	 */
//	protected Sheet sheet;
	
//	private boolean isProtected = false;
	//kazuhiro kobayashi 10/7
	private String protection = NORMAL;
	public static final String PROTECTED = "protected";
	public static final String NORMAL = "normal";
	
	private static int id = 1;
 
	public Region(Spread spread,View view, String uri, String originalURI,String version){
		super();
		baseURI = spread.createOldVersionURI()+""+view.getTypeString()+"/";
		this.spread = spread;
		this.view = view;
		id++;
		this.setId((id-1));
		WorkspaceWindow.setUpdated(true);
		this.isLineSegment = false;
		this.setURIs(uri, originalURI);
		this.setVersion(version);
	}
	public Region(Spread spread, View view) {
		super();
		baseURI = spread.createOldVersionURI()+""+view.getTypeString()+"/";
		this.spread = spread;
		this.view = view;
		id++;
		this.setId((id-1));
		WorkspaceWindow.setUpdated(true);
		this.isLineSegment = false;
		this.setURIs();
	}
	/*
	 * only for Line Segment
	 * need to be refactored
	 */

	protected Region(Spread spread, String type) {
		super();
		baseURI = spread.createOldVersionURI()+""+type+"/";
		this.spread = spread;
		id++;
		this.setId((id-1));
		WorkspaceWindow.setUpdated(true);
		this.isLineSegment = true;
	}



	public View getView(){
		return this.view;
	}
	public void setView(View view){
		this.view = view;
	}
	public Spread getSpread(){
		return this.spread;
	}
//	public Sheet getSheet(){
//		return this.sheet;
//	}
	public boolean contains(Point2D point){
		return this.view.contains(point);
	}
	@Override
	public JPanel createElementViewPanel() throws NoWayToShowException {
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout(5,5));
		Image image = new ImageCropper(this).crop();
		JLabel label = new JLabel();
		if(centermode){
			label.setHorizontalAlignment(JLabel.CENTER);
		}
		ImageIcon icon = new ImageIcon(image);
		label.setIcon(icon);
		panel.add(label);
		return panel;
	}
	@Override
	public JPanel createElementViewPanel(int width, int height) throws NoWayToShowException {
		JPanel panel = new JPanel();

		Image origImage = this.getSpread().getImage();
		BufferedImage bufferedOrigImage = new BufferedImage(origImage.getWidth(null),origImage.getHeight(null),BufferedImage.TYPE_INT_RGB);
		Graphics g = bufferedOrigImage.getGraphics();
		g.drawImage(origImage,0,0,null);

		View view = this.getView();
		boolean tmp = view.isSelected();
		view.setIsEmphasized(true);
		view.draw((Graphics2D)g);
		view.setIsEmphasized(tmp);

		Image croppedImage = new ImageCropper(bufferedOrigImage,this).crop();
		JLabel label = new JLabel();
		if(centermode){
			label.setHorizontalAlignment(JLabel.CENTER);
		}

		ImageIcon icon = new ImageIcon(croppedImage);

		label.setIcon(icon);
		panel.setLayout(new BorderLayout());
		panel.add(label,BorderLayout.CENTER);
		return panel;
	}
	
	public JPanel createElementViewPanelForLocalView() {
		JPanel panel = new JPanel();
		boolean noListner = false;
		Image croppedImage = null;

		File imageFile = this.getSpread().getImageFile();
		Image origImage = this.getSpread().getImage();
		if (imageFile.exists() && origImage !=null){
			BufferedImage bufferedOrigImage = new BufferedImage(origImage.getWidth(null),origImage.getHeight(null),BufferedImage.TYPE_INT_RGB);
			Graphics g = bufferedOrigImage.getGraphics();
			g.drawImage(origImage,0,0,null);

			View view = this.getView();
			boolean tmp = view.isSelected();
			view.setIsEmphasized(true);
			view.draw((Graphics2D)g);
			view.setIsEmphasized(tmp);

			croppedImage = new ImageCropper(bufferedOrigImage,this).cropForLocalView();
		} else if (!imageFile.exists()) {
			// case of image load failure
			noListner = true;
			try {
				croppedImage = ImageIO.read(new File("./icons/no_image_found.png"));
			} catch (IOException e) {
				System.out.println("Failed to generate error message image! In Region.java");
			} 
		} else {
			System.out.println("Failed to load the image file: " + imageFile.toString());
			return null;
		}
		JLabel label = new JLabel();
		if(centermode){
			label.setHorizontalAlignment(JLabel.CENTER);
		}

		ImageIcon icon = new ImageIcon(croppedImage);

		label.setIcon(icon);
		panel.setLayout(new BorderLayout());
		panel.add(label,BorderLayout.CENTER);
		if (! noListner) panel.addMouseListener(new elementViewPanelListener(panel, this));
		return panel;
	}

	protected boolean centermode = false;
	public void setCentermode(boolean centermode) {
		this.centermode = centermode;
	}
	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

	/*
	 * 保護モードに関するメソッド群
	 */
	
	public void setProtection(String protection){
//		isProtected = true;
		//kazuhiro kobayashi 10/7
		this.protection = protection;
	}
//	public void releaseProtection(){
//		isProtected = false;
//		//kazuhiro kobayashi 10/7
//		this.protection = NORMAL;
//	}
	//kazuhiro kobayashi 10/7
	public String isProtected(){
		return this.protection;
	}
	
	//kazuhiro kobayashi 10/7
	//kazuhiro kobayashi 10/9
//	public String getProtection(){
//		return this.protection;
//	}
	
	// ADD northgrid
	public String getBaseURI(){
		return baseURI;
	}
	public Rectangle getRectangle() {
		return this.view.getRectangle();
	}
	
	public List<Point2D> getPoints(){
		return this.points;
	}

	public Point getCenterPoint() {
		int x = (int)this.getRectangle().getCenterX();
		int y = (int)this.getRectangle().getCenterY();
		return new Point(x, y);
	}

	public Point getCornerPoint() {
		int x = (int)this.getRectangle().getX();
		int y = (int)this.getRectangle().getY();
		return new Point(x, y);
	}
	@Override
	public String createURI() {
		return URICreator.createURI(this);
	}

	@Override
	public String getTypeString() {
		return this.view.getTypeString();
	}

	public boolean isLineSegment() {
		return this.isLineSegment;
	}
	@Override
	public void jump() {
		SpreadJumpAction.jumpToMarkup(this);
	}
	@Override
	public void openNewWindow() {
		SpreadOpenAction.openMarkup(this);
	}
	
	@Override
	public String toString() {
		return this.view.getTitle() + ": " + this.uri;
	}
	
	public String getTypeStringForDisplay () {
		return view.getTypeStringForDisplay();
	}
	
	@Override
	public String getTimeZone() {
		return this.timeZone;
	}
	@Override
	public void setTimeZone(String timeZone) {
		this.timeZone = timeZone;
		
	}
	public Image getLinkedImage() {
		int direction = this.getLinkType();
		ImageIcon imageIcon = null;
		if (direction == ResourcePointer.OUT) {
			imageIcon = new ImageIcon(GSConstants.ICON_PATH + "link_out.png");
		} else if (direction == ResourcePointer.IN) {
			imageIcon = new ImageIcon(GSConstants.ICON_PATH + "link_in.png");	
		} else if (direction == ResourcePointer.BOTH) {
			imageIcon = new ImageIcon(GSConstants.ICON_PATH + "link_both.png");
		}
		return imageIcon.getImage();
	}
	public int getLinkType() {;
		return GS_RWRepository.getInstance().getLinkType(this);
	}


}