/* $Id: GSWysiwygMouseListener.java 1096 2016-04-20 13:44:12Z shayashi $ */
package smart_gs.smleditor.swingui;


import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JComponent;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.html.HTML;

import smart_gs.connection.ConnectionCreator;
import smart_gs.drawing_tool.SpreadCanvas;
import smart_gs.drawing_tool.action.JumpWebPageAction;
import smart_gs.drawing_tool.view.RectangleView;
import smart_gs.logical.LineSegment;
import smart_gs.logical.Region;
import smart_gs.logical.TextSegment;
import smart_gs.swingui.AbstractGSWindow;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.swingui.toolbar.action.ShowLocalViewAction;
import smart_gs.util.HrefChecker;
import smart_gs.util.GSWindowByMouseEvent;
import sml_editor.swingui.GSHTMLEditorTextPane;
import sml_editor.swingui.wysiwyg.WysiwygMouseListener;


public class GSWysiwygMouseListener extends WysiwygMouseListener {
	// ADD NorthGird 20090224
	protected boolean markupflg = false;
	
	public GSWysiwygMouseListener(GSEditorTextPane textPane) {
		super(textPane);
	}
	@Override
	public void mouseClicked(MouseEvent e) {
		super.mouseClicked(e);
		if(e.getButton() == MouseEvent.BUTTON3 ||
				/* alternative for right button click */
				(e.getButton() == MouseEvent.BUTTON1 & WorkspaceWindow.getInstance().isAlt())){
			SimpleAttributeSet element = textPane.getSelectID(e.getPoint());
			if(element == null){
				JComponent component = ( JComponent ) e.getSource();
				new GSEditorPopupMenu2(textPane).show(textPane,e.getX() + component.getX(),e.getY() + component.getY());
				return;
			}
			
			boolean href = false;
			String id = (String)element.getAttribute(HTML.Attribute.HREF);
			TextSegment segment = null;
			if(id != null){
				int checkid = HrefChecker.check(id);
				if(checkid == -1){
					href = true;
				}else{
					segment = ((GSEditorTextPane)textPane).getSmartDocument().getSegmentByID(checkid);
					if (segment == null) {
						segment = ((GSEditorTextPane)textPane).getSmartDocument().getZombieSegmentByID(checkid);
					}
				}
				/*
				 * show popup
				 */
				JComponent component = ( JComponent ) e.getSource();
				new GSEditorPopupMenu(segment,textPane,e.getPoint(),href).show(textPane,e.getX() + component.getX(),e.getY() + component.getY());

			}
		}
		if(e.getButton() == MouseEvent.BUTTON1){
			SimpleAttributeSet element = textPane.getSelectID(e.getPoint());
			if(element == null){
				if (e.getClickCount()==2) {
					Element elm = textPane.getElementFromPoint(e.getPoint());
					// ocrで読み取った単語の場合は該当イメージにジャンプする
					if (isOCRWord(elm)){
						jumpToCorrespondingWordInImage(e, elm);					
					}					
					jumpToCorrespondingLineInImage(e);
				}
				return;
			}
			TextSegment segment =  null;
			String id = (String)element.getAttribute(HTML.Attribute.HREF);
			int checkid = HrefChecker.check(id);
			
			//2011/10/16 kukita
			if (element.getAttribute(ConnectionCreator.EXTERNAL_LINK) != null) {
				new JumpWebPageAction(textPane,e.getPoint()).actionPerformed(null);
				return;
			}else{
				segment = ((GSEditorTextPane)textPane).getSmartDocument().getSegmentByID(checkid);
			}
			if(segment != null){
				if(WorkspaceWindow.getInstance().isAlt() == true && WorkspaceWindow.getInstance().isCtrl() == true){
					new ShowLocalViewAction(segment).execute();
				}else if(WorkspaceWindow.getInstance().isAlt()){
					ConnectionCreator.setSource(segment);
				}else if(WorkspaceWindow.getInstance().isCtrl()){
					ConnectionCreator.setTarget(segment);
				}
				if(e.getClickCount() == 2){
					new ShowLocalViewAction(segment).execute();
				}
			}
		}
	}
	
	private void jumpToCorrespondingLineInImage(MouseEvent e) {
		AbstractGSWindow window = (new GSWindowByMouseEvent()).getWindow(e);
		if (window == null) return;
		boolean iscompacteditor=false;
		if (window instanceof GSEditor) {
			if (((GSEditor)window).getEditorType() == GSEditor.COMPACT) {
				iscompacteditor=true;
			}
		}
		GSTabbedPane gsTabbedPane = window.getTabbedPane();
		if (gsTabbedPane.getSelectedIndex() != (iscompacteditor?1:0)) return;
		IDATPanel fstIdatPanel = (IDATPanel)gsTabbedPane.getSelectedComponent();
		GSHTMLEditorTextPane theTextPane = (GSHTMLEditorTextPane)e.getComponent();
		if (theTextPane != fstIdatPanel.getTextPane().getGSHTMLEditorTextPane()) return;
		int pos = theTextPane.getCaretPosition();
		
		char ch = getCharAt(theTextPane,pos);
		char chprev = getCharAt(theTextPane,pos-1);

		String ansString = "";
		int left = 0;
		boolean leftfound = false;	
		
		if (ch == '$'){
			left = pos;
			while (left > 0) {
				left--;
				ch = getCharAt(theTextPane,left);;
				if (! (('0' <= ch && ch <= '9') || ch == '$')) {
					break;
				} else if (ch == '$') {
					if (left == pos - 1) return;
					leftfound = true;
					break;
				}
			}
			if (!leftfound) return;
			try {
				ansString = theTextPane.getText(left,pos-left+1);
				if (ansString.charAt(0)=='$' && ansString.charAt(ansString.length()-1)=='$') {
					jumpToLine(new Integer(ansString.substring(1,ansString.length()-1)),window);
					if (iscompacteditor) window.getTabbedPane().setSelectedIndex(0);
				}
				return;
			} catch (BadLocationException e1) {
				return;
			}
		} else if (chprev == '$'){
			pos--;
			left = pos;
			while (left > 0) {
				left--;
				ch = getCharAt(theTextPane,left);;
				if (! (('0' <= ch && ch <= '9') || ch == '$')) {
					break;
				} else if (ch == '$') {
					if (left == pos - 1) return;
					leftfound = true;
					break;
				}
			}
			if (!leftfound) return;
			try {
				ansString = theTextPane.getText(left,pos-left+1);
				if (ansString.charAt(0)=='$' && ansString.charAt(ansString.length()-1)=='$') {
					int index = new Integer(ansString.substring(1,ansString.length()-1));
					jumpToLine(index,window);
					if (iscompacteditor) window.getTabbedPane().setSelectedIndex(0);
				}
				return;
			} catch (BadLocationException e1) {
				return;
			}
		}
	}


	private void jumpToLine(Integer n,AbstractGSWindow window) {
		SpreadCanvas canvas = window.getSpreadCanvas();
		LineSegment lineseg = canvas.imageLabel.getLineSeg(n);
		Region region = lineseg.transformToPolygonRegion(canvas.getSpread());
		region.setTemporary(true);
		region.setJumpedTo(true);
		canvas.addRegion(region);
		canvas.tmpPolyDeleteAndResetSelection(true);
		canvas.selectRegion(region);
		canvas.imageLabel.showImage();	
		canvas.imageLabel.moveToLine(lineseg.getCornerPoint());
	}
		
	private char getCharAt(GSHTMLEditorTextPane theTextPane, int pos) {
		try {
			return theTextPane.getText(pos,1).charAt(0);
		} catch (BadLocationException e) {
			return 0;
		}
	}
	
	private boolean isOCRWord (Element elm) {
		Object attribute = elm.getAttributes().getAttribute(HTML.Tag.SPAN);
		AttributeSet set = (AttributeSet) attribute;
		String cls = null;
		if (set != null) {
			cls = (String) set.getAttribute(HTML.Attribute.CLASS);	
		}		
		if (cls != null) {
			return cls.equals("ocrx_word");	
		}
		return false;
	}
	
	private void jumpToCorrespondingWordInImage (MouseEvent event, Element elm) {		
		Object attribute = elm.getAttributes().getAttribute(HTML.Tag.SPAN);
		AttributeSet set = (AttributeSet) attribute;
		String bbox = (String) set.getAttribute(HTML.Attribute.TITLE);
		// U+a0のスペースが含まれているのでor条件でマッチ
		String regex = "bbox(?: | )(\\d+)(?: | )(\\d+)(?: | )(\\d+)(?: | )(\\d+)";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(bbox);
		int x = 0;
		int y = 0;
		int w = 0;
		int h = 0;
		if (m.find()) {
			x = Integer.parseInt(m.group(1));
			y = Integer.parseInt(m.group(2));
			w = Integer.parseInt(m.group(3)) - x;
			h = Integer.parseInt(m.group(4)) - y;
		}
		AbstractGSWindow window = (new GSWindowByMouseEvent()).getWindow(event);
		if (window == null) return;		
		SpreadCanvas canvas = window.getSpreadCanvas();
		Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
		RectangleView view = new RectangleView(rect);
		Region region = new Region(canvas.getSpread(), view);
		region.setTemporary(true);
		region.setJumpedTo(true);
		canvas.addRegion(region);
		canvas.tmpPolyDeleteAndResetSelection(true);
		canvas.selectRegion(region);
		canvas.imageLabel.showImage();	
		canvas.imageLabel.moveTo(new Point(x,y));	
	}	
}