package de.visone.nlpext.network;

import java.awt.Frame;
import java.io.File;

import javax.swing.JOptionPane;

import org.apache.log4j.Logger;

import de.visone.base.Mediator;
import de.visone.ext.NetworkUtil;
import de.visone.nlpext.gui.ProgressDialog;
import de.visone.nlpext.gui.ProgressListener;
import de.visone.nlpext.util.Timer;

/**
 * This class handles the creation of all text networks (possibly multiple
 * networks from several files): For each chosen file, the
 * <code>buildNetwork(File file)</code> method is called. Which kind of text
 * network is created, depends on the <code>textNetw</code> field. This class
 * also handles the displaying progress and does a quick layout after network
 * creation.
 * 
 * @author nick
 */
public class CreationProcess implements Runnable, ProgressListener {
	private static final Logger logger = Logger
			.getLogger(CreationProcess.class);

	// TODO disable logging on standard output
	private final boolean logging = false;

	// file that need to be processed
	private final File textFile;

	// the text network object to work on
	private final TextNetwork textNetw;

	// mediator for displaying progress and opening new tabs
	private final Mediator mediator;

	// progress indicating fields
	private ProgressDialog progressDialog;

	/**
	 * Constructs and starts a new network creation process.
	 * 
	 * @param textFile
	 *            the textFiles on which network should be built
	 * @param textNetw
	 *            an already configured TextNetwork doing the creation
	 * @param doLayout
	 *            specifying whether quick layout should be done
	 * @param mediator
	 *            used to open new tabs
	 */
	public CreationProcess(final File textFile, final TextNetwork textNetw,
			final boolean doLayout, final Mediator mediator) {

		this.textFile = textFile;
		this.textNetw = textNetw;
		this.mediator = mediator;

		textNetw.setProgressListener(this);

		new Thread(this).start();
	}

	/**
	 * called when network creation object is instantiated.
	 */
	@Override
	public void run() {
		logger.debug("start network creation");
		try {
			// set progress dialog
			final Frame parentWindow = mediator.getWindow();
			if (mediator.getWindow() != null) {
				progressDialog = new ProgressDialog(parentWindow,
						"Creating Network...", ProgressDialog.STYLE_TWO_BARS);
				progressDialog.setFilename(textFile.getName());
				progressDialog.setTotalProgressLabelText("Processing...");
				progressDialog.setVisible(true);
			}

			// build the network according to text network type
			final Timer creationTimer = new Timer(true);
			logger.debug("building network");
			textNetw.buildNetwork(textFile);
			final long creationTime = creationTimer.getElapsedTime();

			// catch any messages that were generated during creation
			if (textNetw.message != null)
				JOptionPane.showMessageDialog(mediator.getWindow(),
						textNetw.message, "Notification",
						JOptionPane.INFORMATION_MESSAGE);
			if (logging)
				logger.info("Finished Network Creation! Time: " + creationTime
						/ 1000 + " s");

			if (mediator != null) {
				// update the view
				NetworkUtil.updateViews(textNetw.getNetwork());
				// re-enable painting
				mediator.setPaintEnabled(true);
			}
			logger.debug("network creation finished");
			// TODO
			// save the network
			// if (!isCanceled())
			// save(new File(output));

		} catch (final Exception e) {
			logger.error("Something went wrong during network creation...", e);
			e.printStackTrace();
		}

		// close the progress dialog when everything is done
		if (progressDialog != null)
			progressDialog.setVisible(false);

	}

	/** Returns true if the process has been canceled by the user. */
	@Override
	public boolean isCanceled() {
		return progressDialog != null && progressDialog.isCanceled();
	}

	/**
	 * Called by the TextNetwork Object during the network generation to inform
	 * this about the progress in analyzing the text.
	 * 
	 * @param numProcessed
	 *            number of processed elements
	 * @param numTotal
	 *            number of elements to process altogether
	 */
	@Override
	public void setProgress(final int numProcessed, final int numTotal) {

		if (progressDialog != null) {
			final String singleTitle = String.format(
					"parsing sentence %d of %d...", numProcessed + 1, numTotal);
			progressDialog.setSingleProgressLabelText(singleTitle);
			final double singleProgress = numProcessed / (double) numTotal;
			progressDialog.setSingleProgress(singleProgress);
		}
	}

	// ========== save-methods ==========

	/**
	 * Saves this network to a given file.
	 * 
	 * @author endele
	 * */
	public void save(final File file) {
		if (!textNetw.isReadyBuild())
			throw new IllegalStateException(
					"Please call buildNetwork() before saving the graph!");
		mediator.getIOManager().write(file,
				mediator.getBundle(textNetw.getNetwork()));
		if (logging)
			logger.info("Saved to " + file.getAbsolutePath());
	}
}
