package Design  {
    private import ScalarValues::*;
    private import Time::*;

    // Definition of signal types
    item def __type_Gyrometer_rollData {
        attribute rollValue : Integer;
    }

    item def __type_Inclinometer_heelData {
        attribute heelValue : Integer;
    }

    item def __type_ControlConsole_deployRequest;

    item def __type_ControlConsole_retractRequest;

    item def __type_Controller_angleCommand {
        attribute desiredAngle : Integer;
    }

    item def __type_Controller_deployCommand;

    item def __type_Controller_retractCommand;

    part def Block__StabilizerSystem {
    }

    part def Block__Controller {
        attribute desiredAngle : Integer = 0;
        attribute deployOrder : Boolean = false;
        attribute retractOrder : Boolean = false;
        attribute rollValue : Integer = 0;
        attribute heelValue : Integer = 0;

        in item rollData : __type_Gyrometer_rollData;
        in item heelData : __type_Inclinometer_heelData;
        in item deployRequest : __type_ControlConsole_deployRequest;
        in item retractRequest : __type_ControlConsole_retractRequest;

        out item angleCommand : __type_Controller_angleCommand;
        out item deployCommand : __type_Controller_deployCommand;
        out item retractCommand : __type_Controller_retractCommand;
        out item angleCommandStarboard : __type_Controller_angleCommand;
        out item deployCommandStarboard : __type_Controller_deployCommand;
        out item retractCommandStarboard : __type_Controller_retractCommand;
    }

    part def Block__Gyrometer {
        attribute rollValue : Integer = 0;

        out item rollData : __type_Gyrometer_rollData;
    }

    part def Block__Inclinometer {
        attribute heelValue : Integer = 0;

        out item heelData : __type_Inclinometer_heelData;
    }

    part def Block__ControlConsole {
        out item deployRequest : __type_ControlConsole_deployRequest;
        out item retractRequest : __type_ControlConsole_retractRequest;
    }

    part def Block__Actuator {
        attribute requestedAngle : Integer = 0;
        attribute deployRequested : Boolean = false;
        attribute retractRequested : Boolean = false;

        in item angleCommand : __type_Controller_angleCommand;
        in item deployCommand : __type_Controller_deployCommand;
        in item retractCommand : __type_Controller_retractCommand;
    }

    part def Block__Fin {
        attribute angleOfAttack : Integer = 0;
        attribute deployed : Boolean = false;
    }

    //Instances section
    part StabilizerSystem : Block__StabilizerSystem {
        part controller : Block__Controller {
        }

        part gyrometer : Block__Gyrometer {
        }

        part inclinometer : Block__Inclinometer {
        }

        part controlConsole : Block__ControlConsole {
        }

        part portActuator : Block__Actuator {
        }

        part starboardActuator : Block__Actuator {
        }

        part portFin : Block__Fin {
        }

        part starboardFin : Block__Fin {
        }
    }

    enum def CommunicationKind {
        synchronous;
        asynchronous;
    }

    connect StabilizerSystem.gyrometer.rollData to StabilizerSystem.controller.rollData  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.inclinometer.heelData to StabilizerSystem.controller.heelData  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controlConsole.deployRequest to StabilizerSystem.controller.deployRequest  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controlConsole.retractRequest to StabilizerSystem.controller.retractRequest  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.angleCommand to StabilizerSystem.portActuator.angleCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.deployCommand to StabilizerSystem.portActuator.deployCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.retractCommand to StabilizerSystem.portActuator.retractCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.angleCommandStarboard to StabilizerSystem.starboardActuator.angleCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.deployCommandStarboard to StabilizerSystem.starboardActuator.deployCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }

    connect StabilizerSystem.controller.retractCommandStarboard to StabilizerSystem.starboardActuator.retractCommand  {
        communicationKind = CommunicationKind::asynchronous;
        isPrivate = true;
        isLossy = false;
    }
}