/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.diirt.javafx.tools;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

/**
 * Allows the user to select some form of data (e.g. a Gaussian wave or a sine
 * wave) and graphs it.
 * 
 * @author mjchao
 */
abstract public class BaseGraphApp extends Application {
    
    final private DataSelectionPanel pnlData = new DataSelectionPanel();
    private BaseGraphView pnlGraph;
    final private MessagePanel pnlError = new MessagePanel();
    
    abstract public BaseGraphView getGraphView();
    
    @Override
    public void start( Stage stage ) throws Exception {
	this.pnlGraph = getGraphView();
	
	BorderPane mainPanel = new BorderPane();
	    mainPanel.setTop( this.pnlData );
	    mainPanel.setCenter( this.pnlGraph );
	    mainPanel.setBottom( this.pnlError );
	    
	//allow components to shrink
	this.pnlData.setMinSize( 0 , 0 );
	this.pnlGraph.setMinSize( 0 , 0 );
	this.pnlError.setMinSize( 0 , 0 );
	
	
	
	Scene scene = new Scene( mainPanel );
	stage.setTitle( "diirt - BaseGraphApp" );
	stage.setScene( scene );
	stage.setWidth( 500 );
	stage.setHeight( 500 );
	stage.show();
    }
    
    /**
     * Reconnects to the data source with whatever data formula
     * is currently in use.
     */
    public void reconnect() {
	this.pnlData.reselect();
    }
    
    /**
     * Reconnects to the data source using the given data formula.
     * 
     * @param dataFormula the data formula to use
     */
    public void reconnect( String dataFormula ) {
	this.pnlGraph.reconnect( dataFormula );
    }
    
    /**
     * Adds the given data formulae to the list of acceptable data formulae
     * for this graphing application.
     * 
     * @param formulae the formulae to add
     */
    public void addDataFormulae( String... formulae ) {
	for ( String s : formulae ) {
	    DataFormula f = DataFormulaFactory.fromFormula( this.pnlGraph , s );
	    this.pnlData.addDataFormulae( f );
	}
    }
    
    /**
     * Adds the given data formulae to the list of acceptable data formulae
     * for this graphing application.
     * 
     * @param formulae the formula objects to add
     */
    void addDataFormulae( DataFormula... formulae ) {
	this.pnlData.addDataFormulae( formulae );
    }
    
    /**
     * Panel allowing the user to select some data to graph.
     */
    private class DataSelectionPanel extends BorderPane {
	
	/**
	 * the allowed data formulae are stored here and the user can
	 * select from this list
	 */
	final private ComboBox< DataFormula > cboSelectData = new ComboBox< DataFormula >();
	
	public DataSelectionPanel() {
	    this.setCenter( this.cboSelectData );
	    
	    //allow the combo box to stretch out and fill panel completely
	    this.cboSelectData.setMaxSize( Double.MAX_VALUE , Double.MAX_VALUE );
	    
	    //allow the user to select no data
	    DataFormula defaultData = new DataFormula( "[Select]" ) {
		
		@Override
		public void onSelected() {
		    BaseGraphApp.this.reconnect( null );
		}
	    };
	    addDataFormulae( defaultData );
	    this.cboSelectData.setValue( defaultData );
	    
	    //watches for when the user selects a new data formula
	    this.cboSelectData.valueProperty().addListener( new ChangeListener< DataFormula >() {

		@Override
		public void changed(ObservableValue<? extends DataFormula> observable, DataFormula oldValue, DataFormula newValue) {
		    newValue.onSelected();
		}
	    });
	}
	
	/**
	 * Adds the given data formulae objects to the list of acceptable
	 * data formulae.
	 * 
	 * @param f the data formula objects to add
	 */
	final public void addDataFormulae( DataFormula... f ) {
	    this.cboSelectData.getItems().addAll( f );
	}
	
	/**
	 * Reselects the currently selected data formula and reconnects to the 
	 * data source using this data formula.
	 */
	public void reselect() {
	    this.cboSelectData.getValue().onSelected();
	}
    }
    
    /**
     * Panel for displaying any messages that may be received from the data
     * source.
     */
    private class MessagePanel extends BorderPane {
	
    }
}

@@ -250,16 +250,52 @@
 cation;%0A
+import javafx.application.Platform;%0A
 import j
@@ -371,16 +371,50 @@
 eValue;%0A
+import javafx.event.EventHandler;%0A
 import j
@@ -470,16 +470,87 @@
 mboBox;%0A
+import javafx.scene.input.KeyCode;%0Aimport javafx.scene.input.KeyEvent;%0A
 import j
@@ -3007,31 +3007,16 @@
 ComboBox
-%3C DataFormula %3E
  cboSele
@@ -3036,31 +3036,16 @@
 ComboBox
-%3C DataFormula %3E
 ();%0A%09%0A%09p
@@ -3261,24 +3261,69 @@
 AX_VALUE );%0A
+%09    this.cboSelectData.setEditable( true );%0A
 %09    %0A%09    /
@@ -3743,27 +3743,22 @@
 stener%3C 
-DataFormula
+Object
  %3E() %7B%0A%0A
@@ -3817,27 +3817,22 @@
 extends 
-DataFormula
+Object
 %3E observ
@@ -3836,16 +3836,83 @@
 ervable,
+ Object oldValue, Object newValue) %7B%0A%09%09    if ( newValue instanceof
  DataFor
@@ -3916,26 +3916,25 @@
 Formula 
-oldValue, 
+) %7B%0A%09%09%09((
 DataForm
@@ -3936,16 +3936,17 @@
 aFormula
+)
  newValu
@@ -3947,24 +3947,140 @@
 ewValue)
- %7B%0A%09%09   
+.onSelected();%0A%09%09    %7D%0A%09%09    else if ( newValue instanceof String ) %7B%0A%09%09%09DataFormulaFactory.fromFormula( pnlGraph , (String)
  newValu
@@ -4080,16 +4080,18 @@
 newValue
+ )
 .onSelec
@@ -4097,20 +4097,31 @@
 cted();%0A
+%09%09    %7D%0A
 %09%09%7D%0A
+%09%09%0A
 %09    %7D);
@@ -4529,32 +4529,46 @@
 select() %7B%0A%09    
+((DataFormula)
 this.cboSelectDa
@@ -4580,16 +4580,17 @@
 tValue()
+)
 .onSelec

Enable custom data formula on BaseGraphApp