/* $Id: CurrentSearchTextDialog.java 125 2011-03-09 09:49:51Z ohura $ */
package smart_gs.current_text_search;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import smart_gs.swingui.toolbar.GSEditorToolBar;
import sml_editor.swingui.EditorTextPane;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.JRadioButton;
import java.awt.CardLayout;
import java.awt.FlowLayout;

public class CurrentSearchTextDialog extends JDialog {

	private static final long serialVersionUID = 1L;

	private JPanel jContentPane = null;

	private JLabel jLabel = null;

	private JTextField searchField = null;

	protected GSEditorToolBar gsEditorToolBar;
	
	private JCheckBox caseCheckBox = null;

	private JCheckBox regularCheckBox = null;

	private JLabel jLabel1 = null;

	private JTextField replaceField = null;

	private JButton replaceButton = null;

	private JPanel jPanel = null;

	private JPanel jPanel1 = null;

	private JRadioButton forwardButton = null;

	private JRadioButton backwordButton = null;

	private JButton findButton = null;

	private JButton replaceFindButton = null;

	private JButton replaceAllButton = null;
	
	private boolean initflg = true;

	/**
	 * @param owner
	 */
	public CurrentSearchTextDialog(Frame owner,String title) {
		super(owner,title);
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(471, 190);
		this.setResizable(false);
		this.setContentPane(getJContentPane());
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jLabel = new JLabel();
			jLabel.setBounds(new Rectangle(10, 8, 90, 20));
			jLabel.setText("Find:");
			jLabel1 = new JLabel();
			jLabel1.setBounds(new Rectangle(12, 32, 90, 20));
			jLabel1.setText("Replace With:");
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(jLabel, null);
			jContentPane.add(getSearchField(), null);
//			jContentPane.add(getRegularCheckBox(), null);
			jContentPane.add(jLabel1, null);
			jContentPane.add(getReplaceField(), null);
			jContentPane.add(getReplaceButton(), null);
			jContentPane.add(getJPanel(), null);
			jContentPane.add(getJPanel1(), null);
//			jContentPane.add(getForwardButton(), null);
			jContentPane.add(getFindButton(), null);
			jContentPane.add(getReplaceFindButton(), null);
			jContentPane.add(getReplaceAllButton(), null);
		}
		return jContentPane;
	}

	/**
	 * This method initializes searchField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getSearchField() {
		if (searchField == null) {
			searchField = new JTextField();
			searchField.setBounds(new Rectangle(105, 8, 355, 20));
		}
		return searchField;
	}

	/**
	 * This method initializes caseCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getCaseCheckBox() {
		if (caseCheckBox == null) {
			caseCheckBox = new JCheckBox("Case Sensitive",false);
			caseCheckBox.setBounds(new Rectangle(203, 137, 150, 14));
		}
		return caseCheckBox;
	}

	/**
	 * This method initializes regularCheckBox	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getRegularCheckBox() {
		if (regularCheckBox == null) {
			regularCheckBox = new JCheckBox("Regular expressions",false);
			regularCheckBox.setBounds(new Rectangle(46, 131, 150, 14));
		}
		return regularCheckBox;
	}
	

	/**
	 * This method initializes replaceField	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private JTextField getReplaceField() {
		if (replaceField == null) {
			replaceField = new JTextField();
			replaceField.setBounds(new Rectangle(105, 32, 355, 20));
		}
		return replaceField;
	}

	/**
	 * This method initializes replaceButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getReplaceButton() {
		if (replaceButton == null) {
			replaceButton = new JButton();
			replaceButton.setText("Replace");
			replaceButton.setBounds(new Rectangle(236, 123, 110, 24));
			replaceButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					replace();
				}
			});
			replaceButton.setEnabled(false);
		}
		return replaceButton;
	}

	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel() {
		if (jPanel == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(2);
			jPanel = new JPanel();
			jPanel.setLayout(gridLayout);
			jPanel.setBorder(new TitledBorder("Options"));
			jPanel.setBounds(new Rectangle(178, 55, 281, 60));
			jPanel.add(getRegularCheckBox(), null);
			jPanel.add(getCaseCheckBox(), null);
		}
		return jPanel;
	}

	/**
	 * This method initializes jPanel1	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanel1() {
		if (jPanel1 == null) {
			GridLayout gridLayout = new GridLayout();
			gridLayout.setRows(2);
			jPanel1 = new JPanel();
			jPanel1.setLayout(gridLayout);
			jPanel1.setBorder(new TitledBorder("Direction"));
			jPanel1.setBounds(new Rectangle(9, 57, 164, 60));
			ButtonGroup group = new ButtonGroup();
			jPanel1.add(getForwardButton(), null);
			jPanel1.add(getBackwordButton(), null);
			group.add(getForwardButton());
			group.add(getBackwordButton());
		}
		return jPanel1;
	}

	/**
	 * This method initializes forwardButton	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getForwardButton() {
		if (forwardButton == null) {
			forwardButton = new JRadioButton();
			forwardButton.setText("Forward");
			forwardButton.setSelected(true);
			forwardButton.setName("forwardButton");
			forwardButton.setBounds(new Rectangle(227, 82, 132, 21));
		}
		return forwardButton;
	}

	/**
	 * This method initializes backwordButton	
	 * 	
	 * @return javax.swing.JRadioButton	
	 */
	private JRadioButton getBackwordButton() {
		if (backwordButton == null) {
			backwordButton = new JRadioButton();
			backwordButton.setBounds(new Rectangle(226, 96, 116, 21));
			backwordButton.setName("backwordButton");
			backwordButton.setText("Backward");
		}
		return backwordButton;
	}

	/**
	 * This method initializes findButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFindButton() {
		if (findButton == null) {
			findButton = new JButton();
			findButton.setBounds(new Rectangle(10, 123, 110, 24));
			findButton.setText("Find");
			findButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					boolean searchway = true;
					if(forwardButton.isSelected()){
						searchway = true;
					}
					if(backwordButton.isSelected()){
						searchway = false;
					}
					if(initflg){
						if(gsEditorToolBar != null){
							EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
							int ajust = 0;
							if(regularCheckBox.isSelected()){
								ajust = 1;
							}
							if(searchway){
								forwardpoint = regexpoing = lastpoint = startposition = editorTextPane.getSelectionEnd() - ajust;
							}else{
								backwardpoint = regexpoing = lastpoint = startposition = (editorTextPane.getSelectionStart() - 1);
							}
						}
						initflg = false;
					}
					search(searchway,null,false);
				}
			});	
		}
		return findButton;
	}
	/**
	 * This method initializes replaceFindButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getReplaceFindButton() {
		if (replaceFindButton == null) {
			replaceFindButton = new JButton();
			replaceFindButton.setText("Replace/Find");
			replaceFindButton.setBounds(new Rectangle(123, 122, 110, 24));
			replaceFindButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					boolean searchway = true;
					if(forwardButton.isSelected()){
						searchway = true;
					}
					if(backwordButton.isSelected()){
						searchway = false;
					}
					if(initflg){
						if(gsEditorToolBar != null){
							EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
							int ajust = 0;
							if(regularCheckBox.isSelected()){
								ajust = 1;
							}
							if(searchway){
								forwardpoint = regexpoing = lastpoint = startposition = editorTextPane.getSelectionEnd() - ajust;
							}else{
								backwardpoint = regexpoing = lastpoint = startposition = (editorTextPane.getSelectionStart() - 1);
							}
						}
						initflg = false;
					}
					String replace = replaceField.getText();
					replace();
					replace = null;
					if(gsEditorToolBar != null){
						EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
						int ajust = 0;
						if(regularCheckBox.isSelected()){
							ajust = 1;
						}
						if(searchway){
							forwardpoint = regexpoing = lastpoint = startposition = editorTextPane.getSelectionEnd() - ajust;
						}else{
							backwardpoint = regexpoing = lastpoint = startposition = (editorTextPane.getSelectionStart() - 1);
						}
					}
					search(searchway,replace,false);
				}
			});	
		}
		return replaceFindButton;
	}
	/**
	 * This method initializes replaceAllButton	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getReplaceAllButton() {
		if (replaceAllButton == null) {
			replaceAllButton = new JButton();
			replaceAllButton.setText("Replace All");
			replaceAllButton.setBounds(new Rectangle(350, 123, 110, 24));
			replaceAllButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					String replace = replaceField.getText();
					startposition = -1;
					lastpoint = -1;
					regexpoing = -1;
					if(regularCheckBox.isSelected()){
						while(regexReplaceAll()){}
					}else{
//						search(true,replace);
						while(search(true,replace,true)){}
					}
				}
			});				
		}
		return replaceAllButton;
	}
	
	public void setGSEditorToolBar(GSEditorToolBar gsEditorToolBar){
		this.gsEditorToolBar = gsEditorToolBar;
		startposition = -1;
		lastpoint = -1;
		lastsearchway = false;
		forwardpoint=0;
		backwardpoint=0;
		regexpoing = -1;
		initflg = true;
//		searchField.setText("");
	}
	public GSEditorToolBar getGSEditorToolBar(){
		return gsEditorToolBar;
	}
	
	protected int startposition = -1;
	protected boolean lastsearchway=false;
	protected int lastpoint = -1;

	protected boolean search(boolean searchway,String replace,boolean isTextReplaceAll){
		boolean find = false;
		if(gsEditorToolBar != null){
			String searchStr = searchField.getText();
			if(!searchStr.equals("")){
				EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
				if(editorTextPane != null){
					String searchText = null;
					if(gsEditorToolBar.getMode() == 0 || gsEditorToolBar.getMode() == 1){
						searchText = editorTextPane.getPainText();
					}else if(gsEditorToolBar.getMode() == 2){
						searchText = editorTextPane.getSource();
					}
					if(searchText == null){
						searchText = "";
					}else{
						searchText = searchText.replaceAll("\r", "");
					}
					// System.out.println(searchText);
					if(regularCheckBox.isSelected()){
						if(!caseCheckBox.isSelected()){
							searchText = searchText.toLowerCase();
						}
						find = searchRegex(editorTextPane,searchText, searchStr, searchway,replace);
					}else{
						find = searchText(editorTextPane,searchText, searchStr, searchway,caseCheckBox.isSelected(),replace,isTextReplaceAll);
					}
				}
			}
			lastsearchway = searchway;
		}
		return find;
	}
	protected void replace(){
		if(gsEditorToolBar != null){
			String searchStr = searchField.getText();
			if(!searchStr.equals("")){
				EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
				String replaceTerm = replaceField.getText();
				editorTextPane.setReplaceSelection(replaceTerm);
				regexpoing = backwardpoint = forwardpoint = editorTextPane.getSelectionEnd();
			}
		}
	}
	protected boolean searchText(EditorTextPane editorTextPane,String searchText,String searchStr,boolean searchway,boolean bCaseSensitive,String replaceStr,boolean isTextReplaceAll){
		boolean find = false;
		int nextpoition;
		if(searchway){
			if(startposition == -1){
				startposition = 0;
				if(!lastsearchway){
					lastsearchway = true;
				}
			}
			if(!lastsearchway){
				startposition = lastpoint;
			}
			nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
			if(nextpoition != -1){
				if(lastpoint == nextpoition){
					startposition = lastpoint + 1;
					nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
				}
			}
			if(nextpoition == -1){
				if(isTextReplaceAll){
					editorTextPane.setSelection(0,0);
					replaceButton.setEnabled(false);
					replaceAllButton.setEnabled(false);
					find = false;
					return find;
				}
				startposition = 0;
				nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
				if(nextpoition != -1){
					startposition = (nextpoition + 1);
//					nextpoition = editorTextPane.findText(searchStr, replaceStr, false,startposition,searchway);
					lastpoint = nextpoition - searchStr.length();
					replaceButton.setEnabled(true);
					replaceAllButton.setEnabled(true);
					find = true;
				}else{
					editorTextPane.setSelection(0,0);
					replaceButton.setEnabled(false);
					replaceAllButton.setEnabled(false);
					find = false;
				}
			}else{
				startposition = (nextpoition + 1);
				lastpoint = nextpoition - searchStr.length();
				replaceButton.setEnabled(true);
				replaceAllButton.setEnabled(true);
				find = true;
			}
		}else{
			if(startposition == -1){
				startposition = searchText.length();
			}else{
				if(lastsearchway){
					startposition = lastpoint;
					if(startposition < (searchStr.length() -1)){
						startposition = searchText.length();
					}
				}
			}
			nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
			if(nextpoition != -1){
				if(lastpoint == nextpoition){
					startposition = lastpoint - searchStr.length() + 1;
					nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
				}
			}
			if(nextpoition == -1){
				startposition = searchText.length();
				nextpoition = editorTextPane.findText(searchStr, replaceStr, bCaseSensitive,startposition,searchway);
				if(nextpoition != -1){
					startposition = nextpoition - searchStr.length();
					if(startposition < 0){
						startposition = 0;
					}
					lastpoint = nextpoition + searchStr.length();
					replaceButton.setEnabled(true);
					replaceAllButton.setEnabled(true);
					find = true;
				}else{
					editorTextPane.setSelection(0,0);
					replaceButton.setEnabled(false);
					replaceAllButton.setEnabled(false);
					find = true;
				}
			}else{
				startposition = nextpoition - searchStr.length();
				lastpoint = nextpoition + searchStr.length();
				replaceButton.setEnabled(true);
				replaceAllButton.setEnabled(true);
				find = true;
			}
		}
		return find;

	}
	protected int regexpoing = -1;
	protected int forwardpoint=0;
	protected int backwardpoint=0;
	protected boolean searchRegex(EditorTextPane editorTextPane,String searchText,String searchStr,boolean searchway,String replace){
//		String searchStr = "\\b([A-Za-z_]\\w*)\\.(java|class)\\b";
//		String searchText = "Regex.java,2Regex.java, Regex.class";
		boolean find = false;
		Position position = null;
		try{
			Pattern p = Pattern.compile(searchStr);
			String text = null;
			if(regexpoing == -1){
				text = searchText;
				if(searchway){
					regexpoing = 0;
				}else{
					regexpoing = text.length();
				}
			}else{
				if(searchway){
					if(!lastsearchway){
						regexpoing = forwardpoint;
					}
				}else{
					if(lastsearchway){
						regexpoing = backwardpoint;
					}
				}
			}
			if(regexpoing == 0){
				text = searchText;
			}else{
				if(regexpoing >= searchText.length()){
					text = searchText;
					regexpoing = 0;
				}else{
					if(searchway){
						text = searchText.substring(regexpoing, searchText.length());
					}else{
						text = searchText.substring(0,regexpoing);
					}
				}
			}
			Matcher m = p.matcher(text);
    		if(searchway){
				while(m.find()){
//		    		position = new Position((m.start() + 1),(m.end() + 1));
		    		position = new Position((m.start() + 1),(m.end() + 1));
	    			break;
			    }
			    if(position != null){
			    	if(replace != null){
			    		int pos = editorTextPane.setReplaceSelection(regexpoing + position.getStart(),regexpoing + position.getEnd(),replace);
			    		regexpoing = pos -1;
			    		forwardpoint = regexpoing;
		    			backwardpoint = regexpoing - (pos -1);
			    	}else{
				    	editorTextPane.setSelection(regexpoing + position.getStart(),regexpoing + position.getEnd());
				    	regexpoing += (position.getEnd() - 1);
		    			forwardpoint = regexpoing;
		    			backwardpoint = regexpoing - (position.getEnd() - 1);
			    	}
	    			find = true;
					replaceButton.setEnabled(true);
					replaceAllButton.setEnabled(true);
			    }else{
			    	text = searchText;
			    	regexpoing = 0;
			    	m = p.matcher(text);
			    	while(m.find()){
			    		position = new Position((m.start() + 1),(m.end() + 1));
		    			break;
				    }
			    	if(position != null){
				    	if(replace != null){
				    		int pos = editorTextPane.setReplaceSelection(regexpoing + position.getStart(),regexpoing + position.getEnd(),replace);
				    		regexpoing = pos - 1;
				    		forwardpoint = regexpoing;
			    			backwardpoint = regexpoing - (pos - 1);
				    	}else{
				    		editorTextPane.setSelection(regexpoing + position.getStart(),regexpoing + position.getEnd());
				    		regexpoing += (position.getEnd() - 1);
			    			forwardpoint = regexpoing;
			    			backwardpoint = regexpoing - (position.getEnd() - 1);
				    	}
		    			find = true;
						replaceButton.setEnabled(true);
						replaceAllButton.setEnabled(true);
			    	}else{
						startposition = -1;
						regexpoing = 0;
						forwardpoint = 0;
						backwardpoint = 0;
						editorTextPane.setSelection(0,0);
						replaceButton.setEnabled(false);
						replaceAllButton.setEnabled(false);
			    	}
			    }
    		}else{
				while(m.find()){
		    		position = new Position((m.start() + 1),(m.end() + 1));
			    }
			    if(position != null){
			    	if(replace != null){
			    		int pos = editorTextPane.setReplaceSelection(position.getStart(),position.getEnd(),replace);
			    		regexpoing = pos + replace.length();
			    		forwardpoint = pos;
		    			backwardpoint = regexpoing;
			    	}else{
				    	editorTextPane.setSelection(position.getStart(),position.getEnd());
				    	regexpoing = (position.getStart() - 1);
			    		forwardpoint  = (position.getEnd() - 1);
			    		backwardpoint = regexpoing;
			    	}
	    			find = true;
					replaceButton.setEnabled(true);
					replaceAllButton.setEnabled(true);
			    }else{
			    	text = searchText;
			    	regexpoing = 0;
			    	m = p.matcher(text);
					while(m.find()){
			    		position = new Position((m.start() + 1),(m.end() + 1));
				    }
					if(position != null){
				    	if(replace != null){
				    		int pos = editorTextPane.setReplaceSelection(position.getStart(),position.getEnd(),replace);
				    		regexpoing = pos + replace.length();
				    		forwardpoint = pos;
			    			backwardpoint = regexpoing;
				    	}else{
							editorTextPane.setSelection(position.getStart(),position.getEnd());
							regexpoing = (position.getStart() - 1);
				    		forwardpoint  = (position.getEnd() - 1);
				    		backwardpoint = regexpoing;
				    	}
		    			find = true;
						replaceButton.setEnabled(true);
						replaceAllButton.setEnabled(true);
					}else{
						startposition = -1;
						regexpoing = 0;
						forwardpoint = 0;
						backwardpoint = 0;
						editorTextPane.setSelection(0,0);
						replaceButton.setEnabled(false);
						replaceAllButton.setEnabled(false);
					}
			    }
    			
    		}
		}catch(Exception e){
			editorTextPane.setSelection(0,0);
			startposition = -1;
		}
		return find;
	}
	
	protected boolean regexReplaceAll(){
		boolean find = false;
		if(gsEditorToolBar != null){
			String searchStr = searchField.getText();
			if(!searchStr.equals("")){
				EditorTextPane editorTextPane = gsEditorToolBar.getEditorTextPane();
				if(editorTextPane != null){
					String searchText = null;
					int ajust = 1;
					if(gsEditorToolBar.getMode() == 0 || gsEditorToolBar.getMode() == 1){
						searchText = editorTextPane.getPainText();
					}else if(gsEditorToolBar.getMode() == 2){
						ajust = 0;
						searchText = editorTextPane.getSource();
					}
					if(searchText == null){
						searchText = "";
					}else{
						searchText = searchText.replaceAll("\r", "");
					}
					String replaceTerm = replaceField.getText();
					Position position = null;
					try{
						Pattern p = Pattern.compile(searchStr);
						String text = null;
						if(regexpoing == -1){
							text = searchText;
							regexpoing = 0;
						}
						if(regexpoing == 0){
							text = searchText;
						}else{
							if(regexpoing >= searchText.length()){
								text = searchText;
								regexpoing = 0;
							}else{
								text = searchText.substring(regexpoing, searchText.length());
							}
						}
						Matcher m = p.matcher(text);
						while(m.find()){
				    		position = new Position((m.start() + ajust),(m.end() + ajust));
			    			break;
					    }
					    if(position != null){
//					    	editorTextPane.setSelection(regexpoing + position.getStart(),regexpoing + position.getEnd());
					    	int pos = editorTextPane.setReplaceSelection(regexpoing + position.getStart(),regexpoing + position.getEnd(),replaceTerm);
				    		regexpoing = pos;
//				    		regexpoing += (position.getEnd() - 1);
			    			find = true;
					    }else{
							startposition = -1;
							regexpoing = 0;
							forwardpoint = 0;
							backwardpoint = 0;
							editorTextPane.setSelection(0,0);
					    }
			   		}catch(Exception e){
						editorTextPane.setSelection(0,0);
						startposition = -1;
						forwardpoint = 0;
						backwardpoint = 0;
					}
				}
			}
		}
   		return find;
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
