/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2007 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  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 com.approximatrix.draco.fit.ui;

import javax.swing.JDialog;

import com.approximatrix.draco.application.ChildFrame;
import com.approximatrix.draco.application.worker.WorkerListener;
import com.approximatrix.draco.application.worker.WorkerEvent;
import com.approximatrix.draco.fit.LSFit;
import com.approximatrix.draco.fit.LSIterative;
import com.approximatrix.draco.general.ui.InfoWindow;
import com.approximatrix.draco.io.XMLio.AnalysisLoadStore;

public abstract class FitChildDialog extends ChildFrame implements WorkerListener {
	
	/** The icon to be displayed for this child window */
	private static final String PATH_TO_ICON = "/com/approximatrix/draco/main/ui/images/icons/regress.png";
	
	/** The dialog used for status */
	protected ProgressDialog status_dialog = null;
	
	protected LSFit analysis = null;
	
	/**
	 * 
	 */
	public FitChildDialog() {
		super();
		initIcon();
	}

	/**
	 * @param title
	 * @param resizable
	 * @param closable
	 * @param maximizable
	 * @param iconifiable
	 */
	public FitChildDialog(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable) {
		super(title, resizable, closable, maximizable, iconifiable);
		initIcon();
	}

	/**
	 * @param title
	 * @param resizable
	 * @param closable
	 * @param maximizable
	 */
	public FitChildDialog(String title, boolean resizable, boolean closable, boolean maximizable) {
		super(title, resizable, closable, maximizable);
		initIcon();
	}

	/**
	 * @param title
	 * @param resizable
	 * @param closable
	 */
	public FitChildDialog(String title, boolean resizable, boolean closable) {
		super(title, resizable, closable);
		initIcon();
	}

	/**
	 * @param title
	 * @param resizable
	 */
	public FitChildDialog(String title, boolean resizable) {
		super(title, resizable);
		initIcon();
	}

	/**
	 * @param title
	 */
	public FitChildDialog(String title) {
		super(title);
		initIcon();
	}

	/** Retuns the analysis as an LSFit object
	 * 
	 * @return a valid, complete LSFit object
	 */
	public abstract LSFit getAnalysis();
	
	/** Used for restoring an LSFit analysis to a dialog
	 * 
	 * @param values a valid, loaded AnalysisLoadStore dataset
	 */
	public abstract void setAnalysis(AnalysisLoadStore data);
	
	/** All fit dialogs are renamable.
	 * 
	 * @return true
	 * @see com.approximatrix.draco.application.ChildFrame#isRenameable()
	 */
	public boolean isRenameable() {
		return true;
	}
	
	/** Overrides the ChildFrame default icon
	 *
	 */
	private void initIcon() {
		super.setIcon(PATH_TO_ICON);
	}
	
	/** Returns the results name for the window */
	protected abstract String getResultsWindowName();
	
	
	protected void performAnalysis(LSIterative analysis, int max_iterations, double tolerance) {
		status_dialog = new IterativeProgress(this.getTitle(),this.getMainWindow(),analysis, max_iterations, tolerance);
		startAnalysis();
	}
	
	protected void performAnalysis(LSFit analysis) {
		status_dialog = new SimpleProgress(this.getTitle(),this.getMainWindow(),analysis);
		startAnalysis();
	}
	
	/** Launches the actual analysis regardless of the 
	 * type of analysis starting.  Should only be called
	 * from the performAnalysis methods.
	 */
	private void startAnalysis() {
		if(status_dialog != null) {
			status_dialog.addWorkerListener(this);
			status_dialog.start();
		}
	}
	
	/** This method is called, whenever an event is created.
     * @param evt the event object
     */    
    public void workerRequest(WorkerEvent evt) {
		this.analysis = evt.getAnalysis();
		displayResults();
		status_dialog.dispose();
    }
    
    /** Displays the internally stored analysis results in a new InfoWindow
     * requested from the MainWindow
     */
    protected void displayResults() {
    	displayResults(this.analysis);
    }
    
    /** Displays the results of the specified analysis in a new InfoWindow
     * requested from the MainWindow.
     * 
     * @param analysis the analysis to extract the results from
     */
    protected void displayResults(LSFit analysis) {
    	String results = analysis.getResults();
    	this.getMainWindow().openWindow(new InfoWindow(this.getResultsWindowName(),results,false,true));
    }
}
