package smart_gs.network;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.jar.Attributes.Name;

import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JOptionPane;

import smart_gs.debugprint.Debugprint;
import smart_gs.logical.Preference;
import smart_gs.swingui.WorkspaceWindow;
import jp.ac.nii.hcp.client.core.FileAttachmentManager;
import jp.ac.nii.hcp.client.core.HCPController;
import jp.ac.nii.hcp.client.core.ImageContentManager;
import jp.ac.nii.hcp.client.core.ProjectEditor;
import jp.ac.nii.hcp.client.net.AuthenticationCache;
import jp.ac.nii.hcp.client.net.UnauthorizedException;
import jp.ac.nii.hcp.client.shared.ClientConfiguration;
import jp.ac.nii.hcp.client.shared.ClientStatus;
import jp.ac.nii.hcp.client.shared.HCPClientException;
import jp.ac.nii.hcp.shared.model.HCPAttachment;
import jp.ac.nii.hcp.shared.model.HCPDocument;
import jp.ac.nii.hcp.shared.model.HCPImage;
import jp.ac.nii.hcp.shared.model.HCPMaterial;
import jp.ac.nii.hcp.shared.model.HCPProject;
import jp.ac.nii.hcp.shared.model.HCPProjectContent;
import jp.ac.nii.hcp.shared.model.HCPProjectHistory;
import jp.ac.nii.hcp.shared.model.HCPProjectList;
import jp.ac.nii.hcp.shared.model.HCPUserGroup;
import jp.ac.nii.hcp.shared.model.ProjectDifference;

public class ProjectHandler {

	private String action;
	private String repositoryAPIUrl;
	private String authUrl;
	private String imageServerUrl;
	private String workspaceDirectory;
	private HCPProject projectInWorkspace;
	private HCPProject projectInRepository;
	private ClientConfiguration config;
	private HCPController controller;
	private AuthenticationCache authenticationCache;
	private HCPUserGroup group;
	private String newProjectName;
	private String uploadComment;
	private int revision = -1;
	private int headRevision;
	private static ProjectHandler singleton = new ProjectHandler(); 

	public ProjectHandler() {
		this.repositoryAPIUrl = Preference.getInstance().getRepositoryAPIUri();
		this.authUrl = Preference.getInstance().getAuthUri();
		this.imageServerUrl = Preference.getInstance().getImageServerUri();
		this.workspaceDirectory = Preference.getInstance().getWorkspaceDirectory();
		if (this.workspaceDirectory == null) {
			this.workspaceDirectory = 
				JOptionPane.showInputDialog(ProjectExplorer.getInstance(),
						"Workspace directory is not designated.\nInput Workspace directroy.");
			Preference.getInstance().setWorkspaceDirectory(this.workspaceDirectory);
		}
		this.config = this.makeConfiguration();
		this.controller = this.makeHcpController();
	}
	
	public static ProjectHandler getInstance() {
		return singleton;
	}

	public List<HCPProject> getProjectsFromWorkspace() {
		HCPController hcp = HCPController.get(this.workspaceDirectory, this.config);
		return hcp.listProjects();
		//Deal with the error resulted from wrong workspace directory path.
	}
	
	

	public List<HCPProject> getProjectsFromRepository() {
		HCPProjectList list;
		try {
			ArrayList<HCPProjectList> lists = new ArrayList<HCPProjectList>();
			list = this.controller.searchProjects();
			lists.add(list);
			String next = list.next;
			if (list.total == 0) {
				return null;
			}
			int page = 1;
			while (next != null) {
				page++;
				list = this.controller.searchProjects(page);
				next = list.next;
				lists.add(list);
			}
			
			ArrayList<HCPProject> totalList = new ArrayList<HCPProject>();
			for (int i = 0; i < lists.size(); i++) {
				for (int j = 0; j < lists.get(i).projects.size(); j++) {
					totalList.add(lists.get(i).projects.get(j));
				}
			}
			return totalList;
		} catch (IOException e) {
			e.printStackTrace();
			new ShowResultDialog("", e);
		} catch (UnauthorizedException e) {
			e.printStackTrace();
			new ShowResultDialog("", e);
		}
		return null;
	}
	
	public List<HCPProject> getProjectsFromRepository(int page) {
		HCPProjectList hcpProjectList;
		try {
			hcpProjectList = this.controller.searchProjects(page);
			ArrayList<HCPProject> array = new ArrayList<HCPProject>();
			for (int i = 0; i < hcpProjectList.projects.size(); i++) {
				array.add(hcpProjectList.projects.get(i));
			}
			return array;
		} catch (IOException e) {
			e.printStackTrace();
			new ShowResultDialog("", e);
		} catch (UnauthorizedException e) {
			e.printStackTrace();
			new ShowResultDialog("", e);
		}
		return null;
	}


	public String getRepositoryAPIUrl() {
		return repositoryAPIUrl;
	}

	public void setRepositoryAPIUrl(String string) {
		this.repositoryAPIUrl = string;
	}

	public String getAuthUrl() {
		return authUrl;
	}

	public void setAuthUrl(String authUrl) {
		this.authUrl = authUrl;
	}

	public String getImageServerUrl() {
		return imageServerUrl;
	}

	public void setImageServerUrl(String imageServerUrl) {
		this.imageServerUrl = imageServerUrl;
	}

	public String getWorkspaceDirectory() {
		return workspaceDirectory;
	}

	public void setWorkspaceDirectory(String workspaceDirectory) {
		this.workspaceDirectory = workspaceDirectory;
	}

	public void create() {
		if (this.newProjectName == null) {
			new NewProjectDialogFrame().setVisible(true);
		} else {
			try {
				HCPProject project = this.controller.createProject(this.newProjectName);
				ProjectEditor editor;
				try {
					String source = "";
					editor = this.controller.openProject(this.newProjectName);
					editor.addDocument(this.newProjectName, source, "");
					this.newProjectName = null;
					WorkspaceWindow.getInstance().openProject(project,this.workspaceDirectory);
					Preference.getInstance().setWorkspaceDirectory(this.workspaceDirectory);
					ProjectExplorer.getInstance().update();
				} catch (HCPClientException e) {
					e.printStackTrace();
					new ShowResultDialog("Create", e).setVisible(true);
					this.newProjectName = null;
				}
			} catch (HCPClientException e) {
				e.printStackTrace();
				new ShowResultDialog("Create", e).setVisible(true);
				this.newProjectName = null;
			}
		}
	}
	
	private ClientConfiguration makeConfiguration() {
		ClientConfiguration config = new ClientConfiguration();
		config.repositoryAPIURL(this.repositoryAPIUrl);
		config.authURL(this.authUrl);
		config.imageServerURL(this.imageServerUrl);
		return config;
	}

	public void authenticate() {
		if (!this.authenticated()) {
			new AuthFrame("User Authentication", this).setVisible(true);
		} else {
			this.showAlreadyAuthenticatedMessage();
		}
	}

	private ClientConfiguration config() {
		ClientConfiguration config =  new ClientConfiguration();
        config.repositoryAPIURL(this.repositoryAPIUrl);
        config.authURL(this.authUrl);
        config.imageServerURL(this.imageServerUrl);
        return config;
	}
	private HCPController makeHcpController() {
		return HCPController.get(this.workspaceDirectory, this.config());
	}
	

	public List<HCPUserGroup> getGroups(AuthenticationCache auth) throws IOException, UnauthorizedException {
		return this.controller.getGroups(auth);
	}

	public AuthenticationCache makeAuthenticationCache(String id, String pass) throws IOException {
        AuthenticationCache authCache = this.controller.login(id, pass);
        return authCache;
	}

	public void setAuthenticationCache(AuthenticationCache auth) {
		this.authenticationCache = 	auth;
	}

	public AuthenticationCache getAuthenticationCache() {
		return this.authenticationCache;
	}

	public void selectGroup(String action) {
		Debugprint.from();
		Debugprint.message("Action: " + action);
		new SelectGroupFrame(action).setVisible(true);
	}

	public void setGroup(HCPUserGroup group) {
		this.group = group;
	}
	
	private boolean validRevision(int revision) {
		return 0 <= revision && revision <= this.getHeadRevision();
	}

	public void setNewProjectName(String name) {
		this.newProjectName = name;
	}

	public HCPController getController() {
		return this.controller;
		
	}

	public String getAction() {
		return this.action;
	}
	
	public void setAction(String name) {
		this.action = name;	
	}

	public void setRevision(int revision) {
		this.revision = revision;
	}

	public int getRevision() {
		return revision;
	}

	public void setHeadRevision(int headRevision) {
		this.headRevision = headRevision;
	}

	public int getHeadRevision() {
		return headRevision;
	}
	
	public void makeList(JList list, List<HCPProject> projects, String action) throws HCPClientException {
		HCPController controller = this.getController();
		DefaultListModel model = new DefaultListModel();
		if (action == ProjectAction.NONE || action == ProjectAction.DOWNLOAD || action == ProjectAction.SAVE_AS) {
			for (int i = 0; i < projects.size(); i++) {
				model.addElement(projects.get(i).name);
			}
		} else {
			for (int i = 0; i < projects.size(); i++) {
				String name = projects.get(i).name;
				ProjectDifference diff = controller.status(name);
				int revision = diff.revision;
				this.setHeadRevision(diff.revision);
				this.setRevision(diff.revision);
				model.addElement(name + " (head revision: " + revision + ")");
			}
		}
		list.setModel(model);		
	}

	public boolean authenticated() {
		return this.authenticationCache != null;
	}

	public void open(HCPProject project) {
		WorkspaceWindow window = WorkspaceWindow.getInstance();
		window.restoreProject(project);
		window.setFileOpened(true);
		window.autosave(window.getCurrentFile());
		window.unlock();
		window.setLastsave(0);
		window.setCurrentFile(null);
		window.setCurrentProject(project);
	}

	public void register() {
		HCPProject project = this.projectInWorkspace;
		Debugprint.from();
		if (project != null) {
			Debugprint.message("Register project: " + project.name);
		}
		if (!this.authenticated()) {
			Debugprint.message("Not authenticated.");
			this.authenticate();
		} else if (this.group == null) {
			Debugprint.message("Group is not selected.");
			this.selectGroup(action);
		} else if (project == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
			try {
				Debugprint.from();
				Debugprint.message("Register project: " + project.name);
				Debugprint.message("Group name: " + this.group.name);
				
				this.controller.importProject(project.name, this.group.id);
				JOptionPane.showConfirmDialog(ProjectExplorer.getInstance(), "Registered: " + project.name);
				ProjectExplorer.getInstance().update();
			} catch (IOException e) {
				e.printStackTrace();
				new ShowResultDialog("Register New Project", e).setVisible(true);
			} catch (UnauthorizedException e) {
				e.printStackTrace();
				new ShowResultDialog("Register New Project", e).setVisible(true);
			} catch (HCPClientException e) {
				e.printStackTrace();
				new ShowResultDialog("Register New Project", e).setVisible(true);
			}			
		}
	}

	public void upload() {
		if (!this.authenticated()) {
			this.authenticate();
		} else if (this.projectInWorkspace == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
			Debugprint.from();
			CommitDialog.getInstance().setVisible(true);
			String name = this.projectInWorkspace.name;
			String comment = this.uploadComment;
			HCPController controller = this.controller;
			ProjectDifference diff;
			try {
				diff = controller.status(this.projectInWorkspace.name);
			} catch (HCPClientException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				new ShowResultDialog("Commit", e).setVisible(true);
			}
			ProjectDifference commitDiff = null;
			try {
				try {
					commitDiff = controller.commitProject(name, comment, false);
					JOptionPane.showMessageDialog(ProjectExplorer.getInstance(),
							"The project was successfully uploaded: " + name);
					System.out.println(commitDiff);
					ProjectExplorer.getInstance().update();
				} catch (IOException e) {
					e.printStackTrace();
					new ShowResultDialog("Commit", e).setVisible(true);
				} catch (UnauthorizedException e) {
					e.printStackTrace();
					new ShowResultDialog("Commit", e).setVisible(true);
				}
			}catch(HCPClientException e) {
				if(e.getStatus() == ClientStatus.COMMIT_CONFLICTS) {
					//衝突発生時、commitDiffに衝突したコンテンツが格納されている。
					System.out.println(commitDiff);
				} else {
					try {
						throw e;
					} catch (HCPClientException e1) {
						e1.printStackTrace();
						new ShowResultDialog("Commit", e).setVisible(true);
					}
				}
			}
		}
	}
	
	public void download() {
		if (!this.authenticated()) {
			this.authenticate();
		} else if (this.projectInRepository == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
		} else {
			try {
				
				this.controller.checkoutProject(this.projectInRepository.name);
				ProjectExplorer.getInstance().update();
			} catch (IOException e) {
				e.printStackTrace();
				new ShowResultDialog("Download", e).setVisible(true);
			} catch (UnauthorizedException e) {
				e.printStackTrace();
				new ShowResultDialog("Download", e).setVisible(true);
			} catch (HCPClientException e) {
				e.printStackTrace();
				new ShowResultDialog("Download", e).setVisible(true);
			}
		}
	}
	
	public void update() {
		if (!this.authenticated()) {
			this.authenticate();
		} else if (this.projectInWorkspace == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
			try {
				List<HCPProjectContent> notUpdated = new ArrayList<HCPProjectContent>();
//				List<HCPProjectContent> updated = new ArrayList<HCPProjectContent>();
				this.controller.updateProject(this.projectInWorkspace.name, false,
						notUpdated);
				new ShowResultDialog("Update", notUpdated).setVisible(true);
				ProjectExplorer.getInstance().update();

			} catch (IOException e) {
				e.printStackTrace();
				new ShowResultDialog("Update", e).setVisible(true);
			} catch (UnauthorizedException e) {
				e.printStackTrace();
				new ShowResultDialog("Update", e).setVisible(true);
			} catch (HCPClientException e) {
				e.printStackTrace();
				new ShowResultDialog("Update", e).setVisible(true);
			}
		}
	}

	public void saveAs() {
		if (!this.authenticated()) {
			this.authenticate();
		} else if (this.projectInRepository == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
		} else {
			new ExportOptionDialog(this.projectInRepository).setVisible(true);
		}
		
	}

	public void compare() {
		if (this.projectInWorkspace == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
		}

	}
	
	public void remove() {
		if (this.projectInWorkspace == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
			int option = this.showRemovalConfirmDialog();
			if (option == JOptionPane.OK_OPTION) {
				this.controller.removeProject(this.projectInWorkspace.name);
				ProjectExplorer.getInstance().update();
			}
		}
		
	}
	
	private int showRemovalConfirmDialog() {
		return JOptionPane.showConfirmDialog(ProjectExplorer.getInstance(),
				"Do you want to remove \"" + this.projectInWorkspace.name + "\"?",
				"Remove Project",
				JOptionPane.OK_CANCEL_OPTION);
	}

	private void showNoProjectSelectedMessage(String location) {
		JOptionPane.showMessageDialog(null,
				"Select a project from " + location + ".", "Message",
				JOptionPane.INFORMATION_MESSAGE);		
	}
	private void showAlreadyAuthenticatedMessage() {
		JOptionPane.showMessageDialog(null,
				"Already authenticated.", "Message",
				JOptionPane.INFORMATION_MESSAGE);				
	}

	public void setProjectInWorkspace(HCPProject projectInWorkspace) {
		this.projectInWorkspace = projectInWorkspace;
	}

	public HCPProject getProjectInWorkspace() {
		return projectInWorkspace;
	}

	public void setProjectInRepository(HCPProject projectInRepository) {
		this.projectInRepository = projectInRepository;
	}

	public HCPProject getProjectInRepository() {
		return projectInRepository;
	}

	public List<HCPProjectHistory> fetchHistories(String name, int i, int j) throws IOException, UnauthorizedException {
		return this.controller.fetchHistories(name, i, j);
	}

	
	public void perform() {
		if (action == ProjectAction.OPEN) {
			this.open(this.projectInWorkspace);
		} else if (action == ProjectAction.REGISTER) {
			this.register();
		} else if (action == ProjectAction.DOWNLOAD) {
			this.download();
		} else if (action == ProjectAction.UPLOAD) {
			this.upload();
		} else if (action == ProjectAction.SAVE_AS) {
			this.saveAs();
		} else if (action == ProjectAction.UPDATE) {
			this.update();
		} else if (action == ProjectAction.NEW) {
			this.create();
		} else if (action == ProjectAction.AUTHENTICATE) {
			this.authenticate();
		} else if (action == ProjectAction.REMOVE) {
			this.remove();
		} else if (action == ProjectAction.COMPARE) {
			this.compare();
		} else if (action == ProjectAction.ADD_ATTACHMENT) {
			this.addAttachment();
		} else if (action == ProjectAction.DOWNLOAD_IMAGE) {
		}
	}

	private void downloadImage(String id) {
		new ImageDownloadDialog(id).setVisible(true);	
	}

	public List<HCPImage> getImagesFromWorkspace() {
		return null;
	}

	public void addImages() {
		String workspaceDir = Preference.getInstance().getWorkspaceDirectory();
		String imageFolderPath = workspaceDir + "/" + "image";
		JFileChooser fileChooser = new JFileChooser(imageFolderPath);
		fileChooser.setDialogTitle("Select an image");
		int option = fileChooser.showDialog(WorkspaceWindow.getInstance(), "Select");
		if (option != JFileChooser.APPROVE_OPTION) return;
		File file = fileChooser.getSelectedFile();
		int beginIndex = imageFolderPath.length();
		String imagePath = file.getAbsolutePath().substring(beginIndex);
		new AddImageToProjectDialog(WorkspaceWindow.getInstance(), file.getName(), imagePath).setVisible(true);
	}
	
	public void addImages(HCPProject project) {
		String workspaceDir = Preference.getInstance().getWorkspaceDirectory();
		String imageFolderPath = workspaceDir + "/" + "image";
		JFileChooser fileChooser = new JFileChooser(imageFolderPath);
		fileChooser.setDialogTitle("Select an image");
		int option = fileChooser.showDialog(WorkspaceWindow.getInstance(), "Select");
		if (option != JFileChooser.APPROVE_OPTION) return;
		File file = fileChooser.getSelectedFile();
		int beginIndex = imageFolderPath.length();
		String imagePath = file.getAbsolutePath().substring(beginIndex);
		new AddImageToProjectDialog(WorkspaceWindow.getInstance(), file.getName(), imagePath, project).setVisible(true);
	}

	public void addAttachment() {
		if (!ProjectHandler.getInstance().authenticated()) {
			ProjectHandler.getInstance().authenticate();
		} else {
			JFileChooser fileChooser = new JFileChooser(".");
			fileChooser.setDialogTitle("Select an attachment file");
			int option = fileChooser.showDialog(WorkspaceWindow.getInstance(), "Select");
			if (option != JFileChooser.APPROVE_OPTION) return;
			File file = fileChooser.getSelectedFile();
			new AddAttachmentToProjectDialog(WorkspaceWindow.getInstance(), "Add an attachment file", file).setVisible(true);
		}
	}

	public ProjectEditor getEditor(HCPProject project) throws HCPClientException {
		return this.controller.openProject(project.name);
	}

	public FileAttachmentManager getAttachmentManager(String name) throws HCPClientException {
		return this.controller.getAttachmentManager(name);
	}
	
	

	public List<HCPDocument> fetchDocuments() {
		HCPProject project = this.getProjectInRepository();
		if (project == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
			return null;
		}
		String name = project.name;
		HCPProject projectFetched;
		try {
			projectFetched = this.controller.fetchProject(name);
			return projectFetched.documents;
		} catch (IOException e) {
			e.printStackTrace();
			
		} catch (UnauthorizedException e) {
			e.printStackTrace();
		}
		return null;
	}

	public List<HCPMaterial> fetchImages() {
		HCPProject project = this.getProjectInRepository();
		if (project == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
			return null;
		}
		String name = project.name;
		HCPProject projectFetched;
		try {
			projectFetched = this.controller.fetchProject(name);
			return projectFetched.materials;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnauthorizedException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public List<HCPAttachment> fetchAttachments() {
		HCPProject project = this.getProjectInRepository();
		if (project == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
			return null;
		}
		String name = project.name;
		HCPProject projectFetched;
		try {
			projectFetched = this.controller.fetchProject(name);
			return projectFetched.attachments;
		} catch (IOException e) {
			e.printStackTrace();
			
		} catch (UnauthorizedException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void fetchContents() {
		HCPProject project = this.getProjectInRepository();
		if (project == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
			return;
		}
		String name = project.name;
		HCPProject projectFetched;
		try {
			projectFetched = this.controller.fetchProject(name);
			ProjectExplorer.getInstance().browseSelectedProject(projectFetched, Constants.REPOSITORY);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnauthorizedException e) {
			e.printStackTrace();
		}		
	}

	public void editDocument(HCPProject project, String text) throws HCPClientException {
		ProjectEditor editor = this.controller.openProject(project.name);
		editor.setDocument(project.name, text);
	}

	public ImageContentManager getImageManager() {
		return this.controller.getImageManager();
	}

	public void delete() {
		HCPProject project = this.projectInRepository;
		if (project == null) {
			this.showNoProjectSelectedMessage(Constants.REPOSITORY);
			return;
		}
		if (!ProjectHandler.getInstance().authenticated()) {
			ProjectHandler.getInstance().authenticate();
		} else {
			try {
				String name = project.name;
				int option = this.showDeletionConfirmDialog();
				if (option == JOptionPane.OK_OPTION) {
					this.controller.deleteProject(name);
					JOptionPane.showMessageDialog(ProjectExplorer.getInstance(), name + " is deleted.");
					ProjectExplorer.getInstance().update();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnauthorizedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private int showDeletionConfirmDialog() {
		return JOptionPane.showConfirmDialog(ProjectExplorer.getInstance(),
				"Do you want to delete \"" + this.projectInRepository.name + "\" from Repository? \\ The same project in Workspace will also be deleted.",
				"Remove Project",
				JOptionPane.OK_CANCEL_OPTION);
	}

	public void rename() {
		if (this.projectInWorkspace == null) {
			this.showNoProjectSelectedMessage(Constants.WORKSPACE);
		} else {
			String newName = this.showRenameDialog();
			if (validNameForProject(newName)) {
				try {
					this.controller.renameProject(this.projectInWorkspace.name, newName);
					ProjectEditor editor;
					String id = this.projectInWorkspace.name;
					editor = this.controller.openProject(this.newProjectName);
					String source = editor.getDocument(id).source;
					editor.removeDocument(id);
					editor.addDocument(this.newProjectName, source, "");
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (HCPClientException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				ProjectExplorer.getInstance().update();
			} else {
				JOptionPane.showMessageDialog(ProjectExplorer.getInstance(), "Invalid name.");
			}
		}
		
		
	}

	private String showRenameDialog() {
		return JOptionPane.showInputDialog(ProjectExplorer.getInstance(), "Input new name");
	}

	private boolean validNameForProject(String newName) {
		// TODO Auto-generated method stub
		return true;
	}

	public void setUploadComment(String comment) {
		this.uploadComment = comment;
	}

	public void history() {
		String name = this.projectInWorkspace.name;
		try {
			List histories = this.controller.fetchHistories(name, 0, 0);
			String historyString = "";
			for (int i = 0; i < histories.size(); i++) {
				String comment = ((HCPProjectHistory)histories.get(i)).remarks;
				int rev = ((HCPProjectHistory)histories.get(i)).revision;
				String user = ((HCPProjectHistory)histories.get(i)).createdBy.id;
				String date = ((HCPProjectHistory)histories.get(i)).created.toString();
				historyString += "Revision: "+ rev + ", by " + user + " at " + date + "\n   Comment: " + comment + "\n"; 
			}
			JOptionPane.showMessageDialog(ProjectExplorer.getInstance(),
					historyString, "Update History", JOptionPane.INFORMATION_MESSAGE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnauthorizedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}