package smart_gs.network;

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.ScrollPaneLayout;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.Diff;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import jp.ac.nii.hcp.client.core.HCPController;
import jp.ac.nii.hcp.client.net.UnauthorizedException;
import jp.ac.nii.hcp.client.shared.HCPClientException;
import jp.ac.nii.hcp.shared.model.HCPDocument;
import jp.ac.nii.hcp.shared.model.HCPProject;
import jp.ac.nii.hcp.shared.model.HCPProjectContent;
import smart_gs.swingui.WorkspaceWindow;

public class ShowResultDialog extends JDialog {


	private JScrollPane sPane;
	private JList results;
	private JButton ok;
	private JButton compare;
	private JButton updateEditedContents;
	private String action;
	private Collection<HCPProjectContent> editedContents;
	private String projectID;
	
	public ShowResultDialog(String action, Exception e) {
		super(ProjectExplorer.getInstance());
		this.action = action;
		this.setModal(true);
		this.results = new JList();
		DefaultListModel model = new DefaultListModel();
		model.addElement("Not succeeded.");
		model.addElement("Exception: " + e.getMessage());
		this.results.setModel(model);
		this.sPane = new JScrollPane(this.results);
		this.ok = new JButton("OK");
		ok.addActionListener(new OKActionListener(this));
		this.build();
		this.setTitle(this.action + " Result");
		this.setSize(500,300);
		this.getRootPane().setDefaultButton(this.ok);
	}

	public ShowResultDialog(String action, List<HCPProjectContent> reserved, String projectID) {
		super(ProjectExplorer.getInstance());
		this.projectID = projectID;
		this.editedContents = reserved;
		this.action = action;
		this.setModal(true);
		this.results = new JList();
		DefaultListModel model = new DefaultListModel();
		model.addElement(action + " finished.");
		for (int i = 0; i < reserved.size(); i++) {
			model.addElement("Conflict: " + reserved.get(i).id);
		}
		this.results.setModel(model);
		this.sPane = new JScrollPane(this.results);
		this.ok = new JButton("OK");
		this.ok.addActionListener(new OKActionListener(this));
		this.compare = new JButton("Compare edited contents.");
		this.compare.addActionListener(new CompareActionListener(this));
		this.updateEditedContents = new JButton("Update edited contents.");
		this.updateEditedContents.addActionListener(new UpdateEditedContentsActionListener(this));
		this.build();
		this.setTitle(this.action + " Result");
		this.setSize(500,300);		
	}

	private void build() {
		Container pane = this.getContentPane();
		pane.removeAll();
		this.setTitle(this.action);
		this.sPane.setLayout(new ScrollPaneLayout());
		this.getContentPane().add(this.sPane);
		this.getContentPane().add(this.ok);
		
		GroupLayout layout = new GroupLayout(pane);
		pane.setLayout(layout);
		layout.setAutoCreateGaps(true);
		layout.setAutoCreateContainerGaps(true);
		
		layout.setHorizontalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.sPane)
				.addComponent(this.ok)
				.addComponent(this.compare)
				.addComponent(this.updateEditedContents)
			)
		);
	
	
		layout.setVerticalGroup(layout.createSequentialGroup()
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.sPane))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.ok))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.compare))
			.addGroup(layout.createParallelGroup(GroupLayout.Alignment.CENTER)
				.addComponent(this.updateEditedContents)
			)
		);
	}

	
	private class OKActionListener implements ActionListener {

		private ShowResultDialog dialog;
		
		public OKActionListener(ShowResultDialog dialog) {
			this.dialog = dialog;
		}
		
		@Override
		public void actionPerformed(ActionEvent arg0) {
			dialog.dispose();
		}		
	}
	
	private class UpdateEditedContentsActionListener implements ActionListener {

		private ShowResultDialog dialog;

		public UpdateEditedContentsActionListener(ShowResultDialog dialog) {
			this.dialog = dialog;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			// TODO Auto-generated method stub

		}

	}


	private class CompareActionListener implements ActionListener {

		private ShowResultDialog dialog;

		public CompareActionListener(ShowResultDialog dialog) {
			this.dialog = dialog;
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			List<HCPProjectContent> contents = (List<HCPProjectContent>) this.dialog.editedContents;
			ProjectHandler handler = ProjectHandler.getInstance();
			try {
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
				DocumentBuilder builder = factory.newDocumentBuilder();

				HCPProject projectInRepository = handler.fetchProjectFrom(this.dialog.projectID, Constants.REPOSITORY);
				for (int i = 0; i < contents.size(); i++) {
					if (contents.get(i).type.equals(HCPProjectContent.ContentType.DOCUMENT)){
						String contentID = contents.get(i).id;
						HCPDocument hcpDocument = handler.fetchDocument(this.dialog.projectID, contentID);
						Document documentInRepository = builder.parse(new ByteArrayInputStream(hcpDocument.source.getBytes()));
						Document documentInWorkspace = builder.parse(new ByteArrayInputStream(((HCPDocument)contents.get(i)).source.getBytes()));
						Diff diff = new Diff(documentInWorkspace, documentInRepository);
						DetailedDiff detailedDiff = new DetailedDiff(diff);
						new ShowDifferenceWindow(((HCPDocument)contents.get(i)).source, hcpDocument.source, detailedDiff).setVisible(true);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnauthorizedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (HCPClientException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}

	}

}
