package vermilion;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import relative.*;

/**
 * A self-building interface window that shows a machine's controls.
 */
public class JParameterFrame extends JDialog implements Runnable
{
    // TODO: Create a tabbed interface for each channel of a machine being
    // shown on a JParameterFrame.

    /**
     * Indicates that the window is open, for controlling the update thread.
     */
    protected boolean isOpen;

    private MachineBase machine;
    private ArrayList<JLabel> labels;

    /**
     * Creates a frame showing basic controls for handling the parameters on
     * a machine.
     */
    public JParameterFrame(MachineBase m)
    {
        super(Main.window, m.machineID);

        machine = m;

        RelativeLayout rel = new RelativeLayout(null);
        setLayout(rel);

        Dimension size = RelativeLayout.getSuggestedSize(0.33f, 0.08f * machine.parameters.length);

        setMinimumSize(size);
        setSize(size);
        setLocationRelativeTo(Main.window);

        labels = new ArrayList<JLabel>();

        Container panel = getContentPane();
        int height = (int) (1000.0 / machine.parameters.length);

        int index = 0;
        for (ParameterBase param : machine.parameters)
        {
            int top = (int) (index * 1000.0 / machine.parameters.length);

            if (param.parameterType == ParameterBase.PARAMETER_TYPE_SLIDER)
            {
                JLabel l = new JLabel(param.parameterName, JLabel.CENTER);
                panel.add(l, new RelativePlacement(0, top, 250, height));
                rel.registerForFontSizeChanges(l);

                JSlider s = new JSlider(0, 9999);
                panel.add(s, new RelativePlacement(250, top, 500, height));
                s.setValue(((ParameterSlider) param).value);
                s.addChangeListener(new JParameterListenerSlider(param));
                rel.registerForFontSizeChanges(s);

                JLabel d = new JLabel(machine.printParameter(param), JLabel.CENTER);
                panel.add(d, new RelativePlacement(750, top, 250, height));
                rel.registerForFontSizeChanges(d);
                labels.add(d);
            }

            index++;
        }

        this.addWindowListener(new CloseParamWindowListener(this));
        isOpen = true;
        (new Thread(this)).start();
    }

    /**
     * Sets up the basic interface of the main window such as the File menu
     * and the main tab control, including the preferences tab. This is done
     * prior to the creation of other systems, during construction of the
     * window.
     */
    public void setupInterface()
    {
        
    }

    /**
     * Runs a thread that updates the values of the controls as they change
     * on the machine.
     */
    @Override
    public void run()
    {
        try
        {
            while (isOpen)
            {
                int index = 0;
                for (ParameterBase param : machine.parameters)
                {
                    JLabel s = (JLabel) labels.get(index);
                    s.setText(machine.printParameter(param));

                    index++;
                }
                Thread.sleep(150);
            }
        }
        catch (Exception ex) {}
    }
}

/**
 * A WindowListener which allows us to catch the window being closed and
 * shut things down. This simply calls Main.closeFramework() before the
 * window closes.
 */
class CloseParamWindowListener implements WindowListener
{
    private JParameterFrame frame;

    public CloseParamWindowListener(JParameterFrame owner)
    {
        frame = owner;
    }

    @Override
    public void windowClosing(WindowEvent e)
    {
        frame.isOpen = false;
    }

    @Override
    public void windowActivated(WindowEvent e) {}
    @Override
    public void windowDeactivated(WindowEvent e) {}
    @Override
    public void windowIconified(WindowEvent e) {}
    @Override
    public void windowDeiconified(WindowEvent e) {}
    @Override
    public void windowOpened(WindowEvent e) {}
    @Override
    public void windowClosed(WindowEvent e) {}
}