package org.jcon.df.edit.screen.std;

import org.jcon.ba.system.BeanActionClose;
import org.jcon.df.edit.ComponentConfig;
import org.jcon.df.edit.EditEvent;
import org.jcon.df.edit.EditListener;
import org.jcon.df.edit.module.Module;
import org.jcon.df.edit.widget.WidgetSet;
import org.jcon.df.edit.widget.WidgetSetEvent;
import org.jcon.df.edit.widget.WidgetSetView;
import org.jcon.param.Param;
import org.jcon.param.ParamDrivenSupply;
import org.jcon.param.ParamDrivenInfo;
import org.jcon.param.ParamSupplier;
import org.jcon.ui.easylayout.EasyLayout;
import org.jcon.ui.easylayout.EasyLayoutLibraryStd;
import org.jcon.ui.easylayout.EasyLayoutRegistry;
import org.jcon.ui.VisualLib;
import org.jcon.ui.WindowLib;
import org.jcon.ui.PrimeWindow;
import org.jcon.util.DataLib;
import org.jcon.util.GenLib;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//import java.awt.event.KeyEvent;
//import java.awt.event.KeyListener;
import java.util.Vector;

/**
* This class is the standard window for modular screens.
* It handles basic work such as Param, events and Window.
* It is used by the actual type of window desired for a
* system, such as a StackedWindowStd. 
* <p>
* Note - Call init() before doing anthing else.
*
* @author Jack Harich
*/
public class WindowStd implements EditListener,
    ActionListener, ParamDrivenSupply, WidgetSetView,
    BeanActionClose {
    // ScreenView

//---------- Public Fields -------------------------------
public static String STYLE_LIBRARY = "org.jcon.Standard";

//---------- Protected Fields ----------------------------
// Properties
protected String          viewName;
protected Param           param;
protected ParamSupplier   paramSupplier;
// Internal
protected EasyLayout      layout;
protected ComponentConfig componentConfig;
protected WidgetSet       widgetSet;
protected Vector          modules = new Vector(); // All Module
protected boolean         isVisible;

protected PrimeWindow     window = new PrimeWindow();
protected String          windowPosition = "Center";
protected Dimension       windowSize;

//---------- Initialization ------------------------------
static {
    // Register library. Used by some workers
    EasyLayoutLibraryStd library = new EasyLayoutLibraryStd();
    EasyLayoutRegistry.addLibrary(STYLE_LIBRARY, library);
}
public WindowStd() {
    // Create a layout using the library
    layout = EasyLayoutRegistry.createLayout(STYLE_LIBRARY);
    layout.setTopContainer(window.getMainPanel());
    // Config window
    window.setWindowClosingCommand("CloseWindow");
    window.setActionListener(this);
}
//---------- EditListener Implementation -----------------
public void processEditEvent(EditEvent evt) {
    //print(".processEditEvent() - " + evt.getEventTypeString());
}
//---------- ActionListener Implementation ---------------
public void actionPerformed(ActionEvent evt) {
    //print(".actionPerformed() -" + evt.getActionCommand());
}
//---------- ParamDrivenSupply Implementation ------------
public void setParamSupplier(ParamSupplier paramSupplier) {
    this.paramSupplier = paramSupplier;
}
public void setParam(Param param) {
    this.param = param;
}
public Param getParam() {
    if (param == null) {
        paramSupplier.supplyParam(this);
        paramSupplier = null;
    }
    return param;
}
public boolean applyNewParam(Param newParam) {
    window.getMainPanel().removeAll();
    setParam(newParam);
    init();
    return true; // Successful
}
public ParamDrivenInfo getParamDrivenInfo() {
    return null;
}
//---------- WidgetSetView Implementation ----------------
public Window getWindow() {
    return window.getWindow();
}
public String getViewName() {
    return viewName;
}
public void setTitle(String title) {
    window.setTitle(title);
}
//---------- BeanActionClose Implementation --------------
public String canClose() {
    return null; // Yes
}
public void close() {
   try {
       window.closeWindow();
   } catch(Exception ex) { 
       print(".close() - Exception: ");
       ex.printStackTrace();    
   }
}
//---------- Properties ----------------------------------
public WidgetSet getWidgetSet() {
    //print(".getWidgetSet() - returning " + widgetSet);
    return widgetSet;
}
// Return all nested modules
public Vector getAllModules() {
    Vector childModules = new Vector();
    for (int i = 0; i < modules.size(); i++) {
        Module module = (Module)modules.elementAt(i);
        loadChildModules(childModules, module);
    }
    return childModules;
}
// RECURSIVE
private void loadChildModules(Vector childModules, Module module) {
    childModules.addElement(module);
    Vector moduleChildren = module.getChildModules();
    // Recursion stops when no children
    for (int i = 0; i < moduleChildren.size(); i++) {
        Module childModule = (Module)moduleChildren.elementAt(i);
        loadChildModules(childModules, childModule);
    }
}
//----- viewName
public void setViewName(String viewName) {
    this.viewName = viewName;
}
//----- visible
public void setVisible(boolean visible) {
    window.setVisible(visible);
    isVisible = visible;
}
public boolean isVisible() {
    return window.isVisible();
}
//----- title
public String getTitle() {
    return window.getTitle();
}
//----- windowPosition
public void setWindowPosition(String windowPosition) {
    this.windowPosition = windowPosition;
}
public String getWindowPosition() {
    return windowPosition;
}
//----- windowSize
public void setWindowSize(int width, int height) {
    windowSize = new Dimension(width, height);
}
public Dimension getWindowSize() {
    return windowSize;
}
//---------- Public Methods ------------------------------
/**
* This must be called after setParam(). It allows a
* delayed initialization.
*/
public void init() {
    widgetSet = null;
    getParam();
    
    // Prepare window
    window.closeWindow();
    String title = param.getString("Title");
    window.setTitle(title);

    window.setFrame(param.isTrueDefaultTrue("IsFrame"));
    window.setModal(param.isTrueDefaultTrue("IsModal"));
    
    // Add workers with myself as EditListener
    componentConfig = new ComponentConfig(
        layout, param.getParam("Workers"), this);
    componentConfig.config();
    modules = componentConfig.getModules();
    window.initWindow(); // Must be after components added

    if (param.hasProperty("WindowWidth") &&
            param.hasProperty("WindowHeight")) {
        int width = param.getInt("WindowWidth");
        int height = param.getInt("WindowHeight");
        window.getWindow().setSize(width, height);
    } else {
        window.packWindow();
    }
    // Position - Note we already have a non-null default
    if (param.hasProperty("WindowPosition")) {
        windowPosition = param.getString("WindowPosition");
    }
    WindowLib.position(window.getWindow(), windowPosition);
    // Done
    createWidgetSet();
    if (isVisible) setVisible(true); // For re-init
}    
//---------- Private Methods -----------------------------
private void createWidgetSet() {
    widgetSet = new WidgetSet();
    widgetSet.setWidgetSetView(this);
    //----- Controls
    Vector controls = new Vector();
    // These are controls not in a module
    Vector notCons = componentConfig.getControls();
    for (int i = notCons.size(); --i >= 0; ) {
        controls.addElement(notCons.elementAt(i));
    }
    // These are controls in each module
    Vector allModules = getAllModules();
    for (int i = allModules.size(); --i >= 0; ) {
        Module module = (Module)allModules.elementAt(i);
        Vector cons = module.getControls();
        for (int j = cons.size(); --j >= 0; ) {
            controls.addElement(cons.elementAt(j));
        }
    }
    // Done gathering controls
    widgetSet.setControls(controls);
    //----- Modules        
    widgetSet.setModules(allModules);
}
//--- Std
private static void print(String text) {
    System.out.println("WindowStd" + text);
}

} // End class
