package de.visone.nlpext.gui;

import java.io.File;

import de.visone.base.Mediator;
import de.visone.gui.tabs.option.BooleanOptionItem;
import de.visone.gui.tabs.option.InputFileOptionItem;
import de.visone.nlpext.gui.ParserLoadingProcess.ParserLoaderListener;
import edu.stanford.nlp.parser.lexparser.LexicalizedParser;

public abstract class ParserNetworkCard extends NLPPanel implements
		ParserLoaderListener {
	private static final String PARSER_EXT = ".ser.gz";
	private static final String PARSER_FILE_TYPE = "parser serialized configuration file";
	private static final String STANFORD_PARSER_TITLE = "Stanford lexicalized parser";
	private static final String PARSER_FILE_LABEL = "parser file";
	/**
	 * default parser filename. located in visone's working directory. that
	 * should be wherever it's installed, so the user just has to copy the file
	 * there and not worry about it any further.
	 */
	private static final File PARSERFILE = new File("englishPCFG.ser.gz");

	private InputFileOptionItem parserOption;
	private BooleanOptionItem useBuiltinParser;
	protected LexicalizedParser parser;
	private String parserFileName;

	public ParserNetworkCard(final Mediator mediator, final String cardname) {
		super(mediator, cardname);
	}

	@Override
	protected void toggleOptionItemsEnabled() {
		parserOption.setEnabled(!useBuiltinParser.getValue());
		super.toggleOptionItemsEnabled();
	}

	public void addParserOptions() {
		addHeading(STANFORD_PARSER_TITLE);
		useBuiltinParser = new BooleanOptionItem();
		useBuiltinParser.setValue(true);
		affectsOthers(useBuiltinParser);
		addOptionItem(useBuiltinParser, "use builtin");
		parserOption = new InputFileOptionItem(PARSER_FILE_TYPE, PARSER_EXT);
		parserOption.setValue(PARSERFILE);
		addOptionItem(parserOption, PARSER_FILE_LABEL);
	}

	protected String getParserFileName() {
		if (useBuiltinParser.getValue())
			return null;
		return parserOption.getValue().getAbsolutePath();
	}

	protected void loadParser() {
		final String newParserFileName = getParserFileName();
		// need to reload the parser if:
		// - none is loaded
		boolean mustLoadParser = parser == null;
		// - the builtin one is loaded, but an external one selected
		if (parserFileName == null && newParserFileName != null)
			mustLoadParser = true;
		// - an external one is loaded, but the builtin one selected
		if (parserFileName != null && newParserFileName == null)
			mustLoadParser = true;
		// - an external one is loaded, but a different external one is
		// selected
		if (parserFileName != null && newParserFileName != null
				&& !newParserFileName.equals(parserFileName))
			mustLoadParser = true;

		if (mustLoadParser)
			ParserLoadingProcess.loadParser(this, newParserFileName, mediator);
	}

	/** {@inheritDoc} */
	@Override
	public void failLoading(final String filename) {
		parser = null;
		parserFileName = null;
	}

	/** {@inheritDoc} */
	@Override
	public void finishLoading(final LexicalizedParser loadedParser,
			final String filename) {
		parser = loadedParser;
		parserFileName = filename;
	}

}