/*
 * This file is a part of EpnTAPClient.
 * This program aims to provide EPN-TAP support for software clients, like CASSIS spectrum analyzer.
 * See draft specifications: https://voparis-confluence.obspm.fr/pages/viewpage.action?pageId=559861
 * Copyright (C) 2016 Institut de Recherche en Astrophysique et Planétologie.
 *
 * This program is free software: you can
 * redistribute it and/or modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or (at your option) any later
 * version. This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details. You should have received a copy of
 * the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package eu.omp.irap.vespa.votable.gui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.SwingWorker;

/**
 * @author N. Jourdane
 */
public class AcquireTable extends SwingWorker<Void, Void> {

	/** The controller of the VOTable to interact with it while acquiring the VOTable. */
	private AcquireTableInterface ctrl;


	/**
	 * Constructor of ReadTable
	 *
	 * @param ctrl The controller who launched the SwingWorker.
	 */
	public AcquireTable(final AcquireTableInterface ctrl) {
		this.ctrl = ctrl;
		ctrl.setWaitMode(true);
		addPropertyChangeListener(new PropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent event) {
				if ("progress".equals(event.getPropertyName())) {
					String status = Status.getMessageFromProgress((Integer) event.getNewValue());
					ctrl.displayInfo(status, null);
				}
			}
		});
	}

	@Override
	public void done() {
		if (isCancelled()) {
			String status = Status.getMessageFromProgress(getProgress());
			ctrl.displayInfo(status + " interrupted by the user.", null);
		} else {
			ctrl.displayTable();
		}
		ctrl.setWaitMode(false);
	}

	@Override
	protected Void doInBackground() throws Exception {
		if (ctrl.getVOTablePath() == null && ctrl.isUrlSet()) {
			setProgress(Status.DOWNLOADING.getProgress());
			ctrl.downloadVOTable();
			setProgress(Status.DOWNLOADED.getProgress());
		}
		if (ctrl.getVOTable() == null) {
			setProgress(Status.XML_PARSING.getProgress());
			ctrl.parseVOTableXML();
			setProgress(Status.XML_PARSED.getProgress());
		}
		setProgress(Status.DATA_PARSING.getProgress());
		ctrl.parseVOTableData();
		setProgress(Status.DATA_PARSED.getProgress());
		return null;
	}


	/**
	 * The Status enumeration aims to provide all status related to the acquiring table operation,
	 * in order to the display progress to the user.
	 */
	public enum Status {

		/** The data inside the VOTable is parsed, we can display data. */
		DATA_PARSED("VOTable data parsed", 100),
		/** Start to parse the VOTable data. */
		DATA_PARSING("Parsing the VOTable data", 51),
		/** The VOTable is downloaded but not parsed. */
		DOWNLOADED("VOTable downloaded.", 42),
		/** Start to download the VOTable. */
		DOWNLOADING("Downloading the VOTable", 1),
		/** The XML file of the VOTable is parsed, but not the data inside. */
		XML_PARSED("VOTable XML file parsed", 50),
		/** Start to parse the XML file of the VOTable. */
		XML_PARSING("Parsing VOTable XML file", 43);

		/** A message describing the current status, to display to the user. */
		private String message;

		/** A number from 0 to 100, related to the progress of the operation. */
		private int progress;


		/**
		 * Constructor of Status enumeration.
		 *
		 * @param message A message describing the current status, to display to the user.
		 * @param progress A number from 0 to 100, related to the progress of the operation.
		 */
		private Status(String message, int progress) {
			this.message = message;
			this.progress = progress;
		}

		/**
		 * Return a message related to the specified progress.
		 *
		 * @param progress A number from 0 to 100, related to the progress of the operation
		 * @return A message describing the current status, to display to the user.
		 */
		public static String getMessageFromProgress(int progress) {
			for (Status s : Status.values()) {
				if (s.progress == progress) {
					return s.message;
				}
			}
			return "";
		}

		/** @return A message describing the current status, to display to the user. */
		public String getMessage() {
			return message;
		}

		/** @return A number from 0 to 100, related to the progress of the operation. */
		public int getProgress() {
			return progress;
		}
	}
}