/* $Id: ReplaceResultListPanel.java 783 2013-10-22 13:07:54Z ohura $ */
package smart_gs.text_search.swingui;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import com.lightdev.app.shtm.SGSHTMLEditorTextPane;
import com.lightdev.app.shtm.SHTMLEditorKit;

import reasoning_web.logical.NotMarkupException;
import smart_gs.logical.GSResource;
import smart_gs.logical.IDAT;
import smart_gs.logical.Spread;
import smart_gs.logical.URIObject;
import smart_gs.logical.URISolver;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.text_search.logical.*;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.lang.Math;

@SuppressWarnings("serial")
public class ReplaceResultListPanel extends JPanel {
	private int sizeOfResults;
	private int sizeToDisplay;
	private int page = 0;
	private int beginIndex;
	private int endIndex;
	String query;
	String queryReplacePaneText;
	ArrayList<SearchResult> results;
	private JCheckBox selectAllCheckBox;

	public ReplaceResultListPanel(String query, String queryReplacePaneText, int sizeToDisplay, int sizeOfResults,ArrayList<SearchResult> results, JCheckBox selectAllCheckBox){
		super(new GridLayout(sizeToDisplay, 3));
		page = 0;
		this.sizeOfResults = sizeOfResults;
		this.sizeToDisplay = sizeToDisplay;
		this.setPreferredSize(new Dimension(250, 700));
		this.results = results;
		this.query = query;
		this.queryReplacePaneText = queryReplacePaneText;
		this.beginIndex = page*sizeToDisplay; // 最初に表示する result の index
		this.endIndex = Math.min((page+1)*sizeToDisplay-1, sizeOfResults-1); // 最後に表示するresult の index
		this.selectAllCheckBox = selectAllCheckBox;
		showResults();
	}
	
	protected void showResults(){
		removeAll();
		
		WorkspaceWindow win = WorkspaceWindow.getInstance();
		boolean currentSpreadIsUndefined = (win.getSpread() == null);
		
		for(int i=beginIndex; i<=endIndex ; i++){
			final SearchResult result = results.get(i);
			if (currentSpreadIsUndefined && result.isInAnIDAT()) {
				IDAT idat = (IDAT)(URISolver.getResource(result.getDocumentURL()));
				Spread spread = idat.getSpread();
				if (spread != null) {
					win.setSpread(spread);
					win.repaint();
				}
				currentSpreadIsUndefined = false;
			}
			ResultPanel panel1 = ResultPanel.getInstance(result.getTextToShow(), result.getDocumentURL(),result.getIndex());
			this.add(panel1);
			ReplaceResultPanel panel2 = ReplaceResultPanel.getInstance(result.getTextToShow(), queryReplacePaneText, result.getDocumentURL(),result.getIndex());
			this.add(panel2);
			JPanel panel3 = new JPanel();
			JButton replaceButton = new JButton();
			replaceButton.setText("Replace");
			replaceButton.setPreferredSize(new Dimension(100,20));
			replaceButton.setActionCommand("Replace: " + i);
			replaceButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					int replaceIndex = Integer.parseInt(e.getActionCommand().substring("Replace: ".length()));
					ReplaceString(replaceIndex);
					removeIndex(replaceIndex);
					showResults();
				}
			});
			panel3.add(replaceButton);

			final JCheckBox checkBox = new JCheckBox();
			if(result.isSelected()){
				checkBox.setSelected(true);
			}
			checkBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					result.setSelected(checkBox.isSelected());
				}
			});
			panel3.add(checkBox);

			this.add(panel3);
			panel1.setPreferredSize(new Dimension(380, 40));
			panel2.setPreferredSize(new Dimension(380, 40));
		}
		// Add padding for GridLayout
		if(endIndex-beginIndex+1<sizeToDisplay){
			for(int i=0; i<sizeToDisplay-(endIndex-beginIndex+1);i++){
				JPanel emptyPanel1 = new JPanel();
				JPanel emptyPanel2 = new JPanel();
				JPanel emptyPanel3 = new JPanel();
				this.add(emptyPanel1);
				this.add(emptyPanel2);
				this.add(emptyPanel3);
			}

		}
		this.setBorder(new TitledBorder("Results " + (beginIndex+1) + " - " +(endIndex+1)+" of " +sizeOfResults+ " for \"" +query+ "\"" ));
		validate();
	}
	
	protected void ReplaceString(int replaceIndex) {
		SearchResult result = results.get(replaceIndex);
		GSResource resource = URISolver.getResource(result.getDocumentURL());
		try {
			String source = resource.getSource();
			source = source.replaceAll(" ", "&nbsp;");

			// Convert HTML source to plain text using GSHTMLEditorTextPane
			SGSHTMLEditorTextPane tempTextPane = new SGSHTMLEditorTextPane(null, null);
			SHTMLEditorKit htmlKit = new SHTMLEditorKit();
			tempTextPane.setEditorKit(htmlKit);
			source = source.replaceAll(" ", "&nbsp;");
			tempTextPane.setText(source);

			tempTextPane.select(result.getIndex(), result.getIndex()+result.getTextToShow().getLength());
			tempTextPane.replaceSelection(queryReplacePaneText);

			resource.setSource("<xml><html>" + tempTextPane.getText() + "</html></xml>");

			tempTextPane.setEnabled(false);

			if(result.getDocumentURL().startsWith(URIObject.HEADER + URIObject.USERS_NOTE)){
				// For UsersNote
			} else {
				IDAT idat = (IDAT)resource;
				WorkspaceWindow.getInstance().updateSpread(idat.getSpread());
			}

		} catch (NotMarkupException e) {
			e.printStackTrace();
		}
	}

	public void removeIndex(int replaceIndex){
		SearchResult result = results.get(replaceIndex);
		results.remove(replaceIndex);
		sizeOfResults--;

		for(int i = replaceIndex; i<results.size(); i++){
			if(result.getDocumentURL().equals(results.get(i).getDocumentURL())){
				results.get(i).setIndex(results.get(i).getIndex()+(queryReplacePaneText.length()-query.length()));
			}
		}		
	}

	public void back(){
		if(page<=0){
			page =0;
			showResults();
		}else {
			page--;
			updateIndex();
			showResults();
			this.selectAllCheckBox.setSelected(false);
		}
	}
	
	public void next(){
		if((page+1)*sizeToDisplay>=sizeOfResults){
			showResults();
		}else{
			page++;
			updateIndex();
			showResults();
			this.selectAllCheckBox.setSelected(false);
		}
	}

	public boolean isBackButton() {
		if(page<=0){
			return false;
		}
		return true;
	}
	
	public boolean isNextButton() {
		if((page+1)*sizeToDisplay>=sizeOfResults){
			return false;
		}
		return true;
	}
	private void updateIndex() {
		this.beginIndex = page*sizeToDisplay;
		this.endIndex = Math.min((page+1)*sizeToDisplay-1, sizeOfResults-1);
	}

	public void replaceSelected() {
		for(int i=results.size()-1;i>=0;i--){
			if(results.get(i).isSelected()){
				ReplaceString(i);
				removeIndex(i);
			}
		}
		updateIndex();
		showResults();
		this.selectAllCheckBox.setSelected(false);
	}

	public void selectAllThisPage(boolean selected) {
		for(int i=this.beginIndex;i<=this.endIndex;i++){
			results.get(i).setSelected(selected);
		}
		showResults();
	}

	public void selectAll(boolean selected) {
		for(int i=0;i<results.size();i++){
			results.get(i).setSelected(selected);
		}
		showResults();
	}


}
