All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bidib.wizard.mvc.pom.controller.PomProgrammerController Maven / Gradle / Ivy

There is a newer version: 2.0.0-M1
Show newest version
package org.bidib.wizard.mvc.pom.controller;

import java.awt.Point;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import org.bidib.jbidibc.core.AddressData;
import org.bidib.jbidibc.core.DefaultMessageListener;
import org.bidib.jbidibc.core.MessageListener;
import org.bidib.jbidibc.core.enumeration.BoosterState;
import org.bidib.jbidibc.core.enumeration.CommandStationPom;
import org.bidib.jbidibc.core.enumeration.CommandStationState;
import org.bidib.jbidibc.core.enumeration.PomOperation;
import org.bidib.jbidibc.core.enumeration.PomProgState;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.core.utils.CollectionUtils;
import org.bidib.jbidibc.core.utils.NodeUtils;
import org.bidib.wizard.comm.Communication;
import org.bidib.wizard.comm.CommunicationFactory;
import org.bidib.wizard.comm.listener.CommunicationListener;
import org.bidib.wizard.mvc.main.model.Node;
import org.bidib.wizard.mvc.pom.controller.listener.PomProgrammerControllerListener;
import org.bidib.wizard.mvc.pom.model.PomProgrammerModel;
import org.bidib.wizard.mvc.pom.view.PomConfirmDialog;
import org.bidib.wizard.mvc.pom.view.PomProgrammerView;
import org.bidib.wizard.mvc.pom.view.listener.PomProgrammerViewListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vlsolutions.swing.docking.DockingDesktop;

public class PomProgrammerController {
    private static final Logger LOGGER = LoggerFactory.getLogger(PomProgrammerController.class);

    private final Collection listeners =
        new LinkedList();

    private final JFrame parent;

    private final Node node;

    private final int x;

    private final int y;

    private final PomProgrammerModel model = new PomProgrammerModel();

    private PomProgrammerView view;

    private MessageListener messageListener;

    private static AtomicBoolean singleton = new AtomicBoolean();

    public PomProgrammerController(Node node, JFrame parent, int x, int y) {
        this.parent = parent;
        this.node = node;
        this.x = x;
        this.y = y;
    }

    public static boolean isOpened() {
        return singleton.get();
    }

    private void setOpened(boolean opened) {
        singleton.set(opened);
    }

    public void addPomProgrammerControllerListener(PomProgrammerControllerListener l) {
        listeners.add(l);
    }

    private void fireClose() {
        for (PomProgrammerControllerListener l : listeners) {
            l.close();
        }

        // reset the opened flag
        setOpened(false);
    }

    private void fireSendRequest(AddressData decoderAddress, PomOperation operation, int cvNumber, int cvValue) {

        LOGGER.info("Send CV request, decoder addr: {}, operation: {}, cvNumber: {}, value: {}", decoderAddress,
            operation, cvNumber, cvValue);

        CommandStationPom opCode = CommandStationPom.valueOf(ByteUtils.getLowByte(operation.getType()));

        // clear the stored cv value in the programmer model
        model.clearCvValue();

        LOGGER.info("Prepared opCode: {}", opCode);

        for (PomProgrammerControllerListener l : listeners) {
            l.sendRequest(node, decoderAddress, opCode, cvNumber, cvValue);
        }
    }

    public void start(final DockingDesktop desktop) {
        final Communication communication = CommunicationFactory.getInstance();

        view = new PomProgrammerView(model);
        view.addPomProgrammerViewListener(new PomProgrammerViewListener() {
            @Override
            public void close() {
                if (messageListener != null) {
                    LOGGER.info("Remove the message listener.");
                    communication.removeMessageListener(messageListener);

                    messageListener = null;
                }
                fireClose();
            }

            @Override
            public void sendRequest(AddressData decoderAddress, PomOperation operation, int cvNumber, int cvValue) {
                fireSendRequest(decoderAddress, operation, cvNumber, cvValue);
            }

            @Override
            public boolean sendCommandStationStateRequest(boolean activate) {
                LOGGER.info("Set the command station to active mode: {}", activate);

                // check if the command station is running and start command station if not in running mode
                CommandStationState commandStationState = communication.queryCommandStationState(node.getNode());

                // query the boosters in the system
                List boostersToStart = new LinkedList<>();

                for (org.bidib.jbidibc.core.Node node : communication.getNodes()) {
                    if (NodeUtils.hasBoosterFunctions(node.getUniqueId())) {
                        LOGGER.info("+++ Query the booster state for node: {}", node);
                        BoosterState boosterState = communication.queryBoosterState(node);
                        LOGGER.info("+++ The current boosterState: {}", boosterState);
                        // if a booster has no power or is off because of short detected we must show an error
                        // message
                        if (boosterState == null) {
                            // TODO the booster state was not delivered -> show an error
                        }
                        else if (BoosterState.isOffState(boosterState)) {
                            LOGGER.info("The current booster is off: {}", node);

                            boostersToStart.add(node);
                        }
                    }
                }

                //
                if (CommandStationState.isOffState(commandStationState) || CollectionUtils.hasElements(boostersToStart)) {

                    // ask the user if he wants to activate the command station
                    PomConfirmDialog pomConfirmDialog = new PomConfirmDialog(node, true, new Point(x, y));
                    if (JOptionPane.CANCEL_OPTION == pomConfirmDialog.getResult()) {
                        LOGGER.info("User cancelled pomConfirmDialog.");
                        return false;
                    }

                    LOGGER.info("Activate the booster!");
                    communication.boosterOn(node.getNode());

                    LOGGER.info("Activate the command station!");
                    communication.setCommandStationState(node.getNode(), CommandStationState.GO_IGN_WD);

                    for (org.bidib.jbidibc.core.Node booster : boostersToStart) {
                        LOGGER.info("Start the booster: {}", booster);
                        communication.boosterOn(booster);
                    }

                    return true;
                }
                else {
                    LOGGER.info("Set the command station state: {}", commandStationState);
                    model.setCommandStationState(commandStationState);
                }
                return false;
            }
        });

        messageListener = new DefaultMessageListener() {
            @Override
            public void feedbackCv(byte[] address, AddressData decoderAddress, int cvNumber, int cvData) {
                LOGGER.info("CV was received, node addr: {}, decoder address: {}, cvNumber: {}, cvData: {}", address,
                    decoderAddress, cvNumber, cvData);

                updatePomProgState(PomProgState.POM_PROG_OKAY, decoderAddress, cvNumber, cvData);
            }

            @Override
            public void csState(byte[] address, CommandStationState commandStationState) {
                LOGGER.info("The command station state has changed: {}", commandStationState);
                if (ByteUtils.arrayEquals(node.getNode().getAddr(), address)) {
                    LOGGER.info("The state of the selected command station node has changed.");

                    model.setCommandStationState(commandStationState);
                }
                else {
                    LOGGER.warn("Another command station has changed the state.");
                }
            }
        };

        communication.addMessageListener(messageListener);

        communication.addCommunicationListener(new CommunicationListener() {

            @Override
            public void status(String statusText, int displayDuration) {
            }

            @Override
            public void opened(String port) {
            }

            @Override
            public void initialized() {
            }

            @Override
            public void closed(String port) {
                LOGGER.info("The communication is closed.");
                if (view != null) {
                    view.closeDialog();
                    view = null;
                }

                try {
                    communication.removeCommunicationListener(this);
                }
                catch (Exception ex) {
                    LOGGER.warn("Remove communication listener failed.", ex);
                }
            }
        });

        LOGGER.info("Initialize the view.");
        // view.initialize();
        setOpened(true);

        // view.prepareDockable(desktop, x, y);
        view.showDialog(parent, x, y);

    }

    private void updatePomProgState(PomProgState pomProgState, AddressData decoderAddress, int cvNumber, int cvValue) {
        model.updatePomProgResult(pomProgState, decoderAddress, cvNumber, cvValue);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy