contract DAppNodePackageDirectory is Owned,Escapable {

    enum DAppNodePackageStatus {Preparing, Develop, Active, Deprecated, Deleted}

    struct DAppNodePackage {
        string name;
        address repo;
        DAppNodePackageStatus status;
    }

    DAppNodePackage[] DAppNodePackages;

    event PackageAdded(uint indexed idPackage, string name, address repo);
    event PackageUpdated(uint indexed idPackage, string name, address repo);
    event StatusChanged(uint idPackage, DAppNodePackageStatus newStatus);

    /// @notice The Constructor assigns the `escapeHatchDestination` and the
    ///  `escapeHatchCaller`
    /// @param _escapeHatchCaller The address of a trusted account or contract
    ///  to call `escapeHatch()` to send the ether in this contract to the
    ///  `escapeHatchDestination` it would be ideal that `escapeHatchCaller`
    ///  cannot move funds out of `escapeHatchDestination`
    /// @param _escapeHatchDestination The address of a safe location (usu a
    ///  Multisig) to send the ether held in this contract; if a neutral address
    ///  is required, the WHG Multisig is an option:
    ///  0x8Ff920020c8AD673661c8117f2855C384758C572 
    function DAppNodePackageDirectory(
        address _escapeHatchCaller,
        address _escapeHatchDestination
    ) 
        Escapable(_escapeHatchCaller, _escapeHatchDestination)
        public
    {
    }

    /// @notice Add a new DAppNode package
    /// @param name the ENS name of the package
    /// @param repo the AragonPackageManager address of the repo.
    /// @return the idPackage of the new package
    function addPackage (
        string name,
        address repo
    ) onlyOwner public returns(uint idPackage) {
        idPackage = DAppNodePackages.length++;
        DAppNodePackage storage c = DAppNodePackages[idPackage];
        c.name = name;
        c.repo = repo;
        // An event to notify that a new package has been added
        PackageAdded(idPackage,name,repo);
    }

    /// @notice Update a DAppNode package
    /// @param idPackage the id of the package to be changed
    /// @param name the new ENS name of the package
    /// @param repo the new AragonPackageManager address of the repo.
    function updatePackage (
        uint idPackage,
        string name,
        address repo
    ) onlyOwner public {
        require(idPackage < DAppNodePackages.length);
        DAppNodePackage storage c = DAppNodePackages[idPackage];
        c.name = name;
        c.repo = repo;
        // An event to notify that a package has been updated
        PackageUpdated(idPackage,name,repo);
    }

    /// @notice Change the status of a DAppNode package
    /// @param idPackage the id of the package to be changed
    /// @param newStatus the new status of the package
    function changeStatus(
        uint idPackage,
        DAppNodePackageStatus newStatus
    ) onlyOwner public {
        require(idPackage < DAppNodePackages.length);
        DAppNodePackage storage c = DAppNodePackages[idPackage];
        c.status = newStatus;
        // An event to notify that the status of a packet has been updated
        StatusChanged(idPackage, newStatus);
    }

    /// @notice Returns the information of a DAppNode package
    /// @param idPackage the id of the package to be changed
    /// @return name the new name of the package
    /// @return repo the AragonPackageManager address of the repo.
    /// @return status the status of the package
    function getPackage(uint idPackage) constant public returns (
        string name,
        address repo,
        DAppNodePackageStatus status
    ) {
        require(idPackage < DAppNodePackages.length);
        DAppNodePackage storage c = DAppNodePackages[idPackage];
        name = c.name;
        repo = c.repo;
        status = c.status;
    }

    /// @notice its goal is to return the total number of DAppNode packages
    /// @return the total number of DAppNode packages
    function numberOfDAppNodePackages() view public returns (uint) {
        return DAppNodePackages.length;
    }
}
/// @title DAppNodePackageDirectory Contract
/// @author Eduardo Antuña
/// @dev The goal of this smartcontrat is to keep a list of available packages 
///  to install in the DAppNode
function numberOfDAppNodePackages() view public returns (uint) {
    return DAppNodePackages.length;
}

/// @notice its goal is to return the total number of DAppNode packages
/// @return the total number of DAppNode packages