/* $Id: GSTabbedPane.java 664 2013-02-14 12:09:43Z ohura $ */
package smart_gs.smleditor.swingui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import smart_gs.current_text_search.SearchDialogManager;
import smart_gs.drawing_tool.SpreadCanvas;
import smart_gs.logical.IDAT;
import smart_gs.logical.Spread;
import smart_gs.logical.TextSegment;
import smart_gs.swingui.IDATNameInGSTabbedPaneManager;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.swingui.toolbar.GSEditorToolBar;
import sml_editor.swingui.EditorTextPane;
import sml_editor.swingui.GSHTMLEditorTextPane;

@SuppressWarnings("serial")
public class GSTabbedPane extends JTabbedPane implements ChangeListener{
	
	protected SpreadCanvas canvas;
	protected IDATPanel firstIDATPanel;
	protected IDATPanel secondIDATPanel;
	protected IDATPanel thirdIDATPanel;
	
	protected Spread spread;
	protected GSEditorFrame parent;
	
	public GSTabbedPane(){
//		super(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
		this.add(new JPanel());
	}
	
	public GSTabbedPane(GSEditorFrame parent,Spread spread){
		this.parent = parent;
		this.spread = spread;
		this.canvas = new SpreadCanvas(spread);
		this.canvas.setGSTabbedPane(this);

		this.firstIDATPanel = new FirstIDATPanel(parent,spread.getFirstIDAT());
		this.secondIDATPanel = new SecondIDATPanel(parent,spread.getSecondIDAT());
		this.thirdIDATPanel = new ThirdIDATPanel(parent,spread.getThirdIDAT());
		
		this.firstIDATPanel.resetCaretPosition();
		this.secondIDATPanel.resetCaretPosition();
		this.thirdIDATPanel.resetCaretPosition();

		this.addTab("Image",this.canvas);
		this.addTab(spread.getFirstIDATName(),this.firstIDATPanel);
		this.addTab(spread.getSecondIDATName(),this.secondIDATPanel);
		this.addTab(spread.getThirdIDATName(),this.thirdIDATPanel);

//		this.addChangeListener(this);
//		2011.02.24 shayashi added
		TabTitleEditListener l = new TabTitleEditListener(this);
		this.addChangeListener(l);
		this.addMouseListener(l);
		this.addMouseListener(new GSTabbedPaneMouseAdapter(parent));
	}
	public SpreadCanvas getSpreadCanvas(){
		return this.canvas;
	}


	public void updateGUI(Spread spread) {
		GSEditor parent = ((GSEditor) this.parent);
		GSTabbedPane oldTabbedPane = parent.getTabbedPane();
		int selectedTab = this.getSelectedIndex();

		parent.setTitle("Editor: " + spread.getName());

		oldTabbedPane.removeAll();

		this.firstIDATPanel = new FirstIDATPanel(parent, spread.getFirstIDAT());
		this.secondIDATPanel = new SecondIDATPanel(parent, spread.getSecondIDAT());
		this.thirdIDATPanel = new ThirdIDATPanel(parent, spread.getThirdIDAT());
		
		this.addTab("Image", this.canvas);
		this.addTab(spread.getFirstIDATName(), this.firstIDATPanel);
		this.addTab(spread.getSecondIDATName(), this.secondIDATPanel);
		this.addTab(spread.getThirdIDATName(), this.thirdIDATPanel);
		this.setSelectedIndex(selectedTab);
		
		TabTitleEditListener l = new TabTitleEditListener(this);
		this.addChangeListener(l);
		this.addMouseListener(l);
		this.addMouseListener(new GSTabbedPaneMouseAdapter(parent));

		parent.setURL(spread.getURI());
		parent.updateWindowListener();
	}

	public Spread getSpread(){
		return this.spread;
	}
	public Point getCornerPoint(){
		return this.canvas.getCornerPoint();
	}
	public void setPanelToShow(int type){
		this.setSelectedIndex(type);
	}
	public void save() {
		if(this.firstIDATPanel != null){
			this.firstIDATPanel.save();
		}
		if(this.secondIDATPanel != null){
			this.secondIDATPanel.save();
		}
		if(this.thirdIDATPanel != null){
			this.thirdIDATPanel.save();
		}
	}	
	public void emphasize(String id) {
		this.firstIDATPanel.emphasize(id);
		this.secondIDATPanel.emphasize(id);
		this.thirdIDATPanel.emphasize(id);
	}
	public void emphasize(TextSegment segment) {
		String id = segment.getId() + "";
		int index = ((IDAT)segment.getDocument()).getType();
		this.setSelectedIndex(index-1);
		this.emphasize(id);
	}
	public void emphasize(int idat_index, int start, int length) {
		switch (idat_index) {
			case 1: 
				this.firstIDATPanel.emphasize(start, length);
				break;
			case 2:
				this.secondIDATPanel.emphasize(start, length);
				break;
			case 3:
				this.thirdIDATPanel.emphasize(start, length);
				break;
			default:
				System.out.println("Error in emphasize(int idat_index, int start, int end) ");
				break;
		}
	}
	
	public Component getTabbedPaneImageCanvas() {
		return this.canvas;
	}
	
	public void updateText() {
		this.firstIDATPanel.updateText();
		this.secondIDATPanel.updateText();
		this.thirdIDATPanel.updateText();
	}
	public void clear(){
		if(this.firstIDATPanel != null){
			this.firstIDATPanel.removeAll();
		}
		if(this.secondIDATPanel != null){
			this.secondIDATPanel.removeAll();
		}
		if(secondIDATPanel != null){
			this.secondIDATPanel.removeAll();
		}
		if(canvas != null){
			this.canvas.clear();
			this.canvas=null;
		}
	}
	public boolean isAvailable(){
		if(canvas == null || this.firstIDATPanel == null || this.secondIDATPanel == null || this.thirdIDATPanel == null){
			return false;
		}
		return true;
	}
	
	public void updateFirstIDAT(String source) {
		this.firstIDATPanel.getTextPane().setSource(source);
	}
	public void updateSecondIDAT(String source) {
		this.secondIDATPanel.getTextPane().setSource(source);
	}
	public void updateThirdIDAT(String source) {
		this.thirdIDATPanel.getTextPane().setSource(source);
	}
	public String getFirstIDATSource() {
		return this.firstIDATPanel.getTextPane().getSource();
	}
	public String getSecondIDATSource() {
		return this.secondIDATPanel.getTextPane().getSource();
	}
	public String getThirdIDATSource() {
		return this.thirdIDATPanel.getTextPane().getSource();
	}
	public GSEditorTextPane getFirstIDAT() {
		return this.firstIDATPanel.getTextPane();
	}
	public IDATPanel getFirstIDATPanel() {
		return this.firstIDATPanel;
	}
	public GSEditorTextPane getSecondIDAT() {
		return this.secondIDATPanel.getTextPane();
	}
	public GSEditorTextPane getThirdIDAT() {
		return this.thirdIDATPanel.getTextPane();
	}
	
	public String getURI(){
		if(this.spread == null){
			return null;
		}
		return this.spread.getURI();
	}

	public void stateChanged(ChangeEvent e) {
		if(this.parent != null){
			Component comp = this.getComponent(this.getSelectedIndex());
			if(comp != null){
				if(comp instanceof IDATPanel){
					if(this.parent instanceof WorkspaceWindow){
						this.parent.setEditorTextPane(((IDATPanel)comp).getTextPane());
//						((WorkspaceWindow)this.parent).getGSEditorToolBar().tabChanged();
					}else if(this.parent instanceof GSEditor){
						this.parent.setEditorTextPane(((IDATPanel)comp).getTextPane());
//						((GSEditor)this.parent).getGSEditorToolBar().tabChanged();
					}
				}else{
					if(this.parent instanceof WorkspaceWindow){
//						((WorkspaceWindow)this.parent).getGSEditorToolBar().check(null);
					}else if(this.parent instanceof GSEditor){
//						((GSEditor)this.parent).getGSEditorToolBar().check(null);
					}
				}
			}
		}
	}
	
	// 20080916 hashimoto.
	// 現在選択されているタブで、カーソルを与えられたインデックスに移動させるメソッド
	public void setCaret(int index){
		IDATPanel panel;
		panel = (IDATPanel)getSelectedComponent();
//		panel.getTextPane().getGSHTMLEditorTextPane().requestFocus();
		GSHTMLEditorTextPane gsHTMLEditorTextPane;
		gsHTMLEditorTextPane = panel.getTextPane().getGSHTMLEditorTextPane();
		gsHTMLEditorTextPane.addFocusListener(new GSEditorFocusListener(gsHTMLEditorTextPane,(index)));
		panel.getTextPane().getGSHTMLEditorTextPane().requestFocus();
	}
	
	class GSEditorFocusListener implements FocusListener{
		protected GSHTMLEditorTextPane gsHTMLEditorTextPane;
		protected int index;
		public GSEditorFocusListener(GSHTMLEditorTextPane gsHTMLEditorTextPane,int index){
			this.gsHTMLEditorTextPane = gsHTMLEditorTextPane;
			this.index = index;
		}
		public void focusGained(FocusEvent e) {
			gsHTMLEditorTextPane.setCaretPosition(index);
			gsHTMLEditorTextPane.removeFocusListener(this);
		}
		public void focusLost(FocusEvent e) {
		}
	}
	
	public GSEditorFrame getParentFrame(){
		return parent;
	}
	
	
	// 2011.02.24 shayashi
	class TabTitleEditListener extends MouseAdapter implements ChangeListener{
	    private final JTextField editor = new JTextField();
	    private final GSTabbedPane tabbedPane;
	    public TabTitleEditListener(final GSTabbedPane tabbedPane) {
	        this.tabbedPane = tabbedPane;
	        editor.setBorder(BorderFactory.createEmptyBorder());
	        editor.addFocusListener(new FocusAdapter() {
	            @Override public void focusLost(FocusEvent e) {
	                renameTabTitle();
	            }
	        });
	        editor.addKeyListener(new KeyAdapter() {
	            @Override public void keyPressed(KeyEvent e) {
	                if(e.getKeyCode()==KeyEvent.VK_ENTER) {
	                    renameTabTitle();
	                }else if(e.getKeyCode()==KeyEvent.VK_ESCAPE) {
	                    cancelEditing();
	                }else{
	                    editor.setPreferredSize((editor.getText().length()>len)?null:dim);
	                    tabbedPane.revalidate();
	                }
	            }
	        });
	        tabbedPane.getInputMap(JComponent.WHEN_FOCUSED).put(
	            KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "start-editing");
	        tabbedPane.getActionMap().put("start-editing", new AbstractAction() {
	            @Override public void actionPerformed(ActionEvent e) {
	                startEditing();
	            }
	        });
	    }
	    @Override public void stateChanged(ChangeEvent e) {
	        renameTabTitle();
	    }
	    @Override public void mouseClicked(MouseEvent me) {
	        Rectangle rect = tabbedPane.getUI().getTabBounds(tabbedPane, tabbedPane.getSelectedIndex());
	        if(rect!=null && rect.contains(me.getPoint()) && me.getClickCount()==2) {
	            startEditing();
	        }else{
	            renameTabTitle();
	        }
	    }
	    private int editing_idx = -1;
	    private int len = -1;
	    private Dimension dim;
	    private Component tabComponent = null;
	    private void startEditing() {
	        editing_idx = tabbedPane.getSelectedIndex();
	        tabComponent = tabbedPane.getTabComponentAt(editing_idx);
	        System.out.print(editing_idx);
	        tabbedPane.setTabComponentAt(editing_idx, editor);
	        editor.setVisible(true);
	        editor.setText(tabbedPane.getTitleAt(editing_idx));
	        editor.selectAll();
	        editor.requestFocusInWindow();
	        len = editor.getText().length();
	        dim = editor.getPreferredSize();
//	        editor.setMinimumSize(dim);
	    }
	    private void cancelEditing() {
	        if(editing_idx>=0) {
	            tabbedPane.setTabComponentAt(editing_idx, tabComponent);
	            editor.setVisible(false);
	            editing_idx = -1;
	            len = -1;
	            tabComponent = null;
	            editor.setPreferredSize(null);
	            tabbedPane.requestFocusInWindow();
	        }
	    }
	    private void renameTabTitle() {
	    	Spread spread = tabbedPane.getSpread();
	    	String title = editor.getText().trim();
	    	if(editing_idx>=0 && !title.equals("Image")) {
	    		int index = editing_idx;
	    		//	            In the tabbed pane of the main fram, the image is not included.
	    		//	            Thus the title of firstIDAT is not "Image".
	    		if (tabbedPane.getTitleAt(0) == "Image") index--;

	    		if ((index == 0 && ! title.equals(spread.getSecondIDATName()) && ! title.equals(spread.getThirdIDATName()))
	    				||(index == 1 && ! title.equals(spread.getFirstIDATName()) && ! title.equals(spread.getThirdIDATName()))
	    				||(index == 2 && ! title.equals(spread.getFirstIDATName()) && ! title.equals(spread.getSecondIDATName()))) {
	    			if (index == 0) 
	    				spread.setFirstIDATName(title);
	    			else if (index == 1)
	    				spread.setSecondIDATName(title);
	    			else 
	    				spread.setThirdIDATName(title);
	    		}
	    		IDATNameInGSTabbedPaneManager.updateTabtitles();
	    	}
	    	cancelEditing();
	    }
	}

	public void setEditorTextPane(EditorTextPane textPane) {
		int tabIndex = this.getSelectedIndex();
		if(tabIndex == indexOfComponent(this.firstIDATPanel)) {
			this.firstIDATPanel.setEditorTextPane(textPane);
		}
		if(tabIndex == indexOfComponent(this.secondIDATPanel)) {
			this.secondIDATPanel.setEditorTextPane(textPane);
		}
		if(tabIndex == indexOfComponent(this.thirdIDATPanel)) {
			this.thirdIDATPanel.setEditorTextPane(textPane);
		}
	}

	public GSEditorToolBar getGSEditorToolBar() {
		int tabIndex = this.getSelectedIndex();
		if(tabIndex == indexOfComponent(this.firstIDATPanel)
				&& indexOfComponent(this.firstIDATPanel) != -1) {
			return this.firstIDATPanel.getGSEditorToolBar();
		}
		if(tabIndex == indexOfComponent(this.secondIDATPanel)
				&& indexOfComponent(this.secondIDATPanel) != -1) {
			return this.secondIDATPanel.getGSEditorToolBar();
		}
		if(tabIndex == indexOfComponent(this.thirdIDATPanel)
				&& indexOfComponent(this.thirdIDATPanel) != -1) {
			return this.thirdIDATPanel.getGSEditorToolBar();
		}
		return null;
	}

	class GSTabbedPaneMouseAdapter extends MouseAdapter {
		private GSEditorFrame parent;

		public GSTabbedPaneMouseAdapter(GSEditorFrame parent){
			this.parent = parent;
		}
		public void mouseEntered(MouseEvent me){
			if(parent instanceof WorkspaceWindow) {
				SearchDialogManager.setGSEditorToolBar(WorkspaceWindow.getInstance().getGSEditorToolBar());
			} else if(parent instanceof GSEditor) {
				SearchDialogManager.setGSEditorToolBar(((GSEditor) parent).getGSEditorToolBar());
			}
		}

	}

	public Object getLineSegEditorToolBar() {
		// TODO Auto-generated method stub
		return null;
	}
}






