contract EtherLambosCore is EtherLambosTuning {

    // This is the main EtherLambos contract. In order to keep our code seperated into logical sections,
    // we've broken it up in two ways. First, we have several seperately-instantiated sibling contracts
    // that handle sales. The sales are
    // seperate since their logic is somewhat complex and there's always a risk of subtle bugs. By keeping
    // them in their own contracts, we can upgrade them without disrupting the main contract that tracks
    // lambo ownership. 
    //
    // Secondly, we break the core contract into multiple files using inheritence, one for each major
    // facet of functionality of EtherLambos. This allows us to keep related code bundled together while still
    // avoiding a single giant file with everything in it. The breakdown is as follows:
    //
    //      - EtherLambosBase: This is where we define the most fundamental code shared throughout the core
    //             functionality. This includes our main data storage, constants and data types, plus
    //             internal functions for managing these items.
    //
    //      - EtherLambosAccessControl: This contract manages the various addresses and constraints for operations
    //             that can be executed only by specific roles. Namely CEO, CFO and COO.
    //
    //      - EtherLambosOwnership: This provides the methods required for basic non-fungible token
    //             transactions, following the draft ERC-721 spec (https://github.com/ethereum/EIPs/issues/721).
    //
    //      - EtherLambosSale: Here we have the public methods for sales. 
    //
    //      - EtherLambosBuilding: This final facet contains the functionality we use for creating new cars.
    //             

    // Set in case the core contract is broken and an upgrade is required
    address public newContractAddress;

    /// @notice Creates the main EtherLambos smart contract instance.
    function EtherLambosCore() public {
        // Starts paused.
        paused = true;

        // the creator of the contract is the initial CEO
        ceoAddress = msg.sender;

        // the creator of the contract is also the initial COO
        cooAddress = msg.sender;

        // start with the car 0 
        _createLambo(uint256(-1), address(0),0);
    }

    /// @dev Used to mark the smart contract as upgraded, in case there is a serious
    ///  breaking bug. This method does nothing but keep track of the new contract and
    ///  emit a message indicating that the new address is set. It's up to clients of this
    ///  contract to update to the new contract address in that case. (This contract will
    ///  be paused indefinitely if such an upgrade takes place.)
    /// @param _v2Address new address
    function setNewAddress(address _v2Address) external onlyCEO whenPaused {
        // See README.md for updgrade plan
        newContractAddress = _v2Address;
        ContractUpgrade(_v2Address);
    }

    /// @notice No tipping!
    /// @dev Reject all Ether from being sent here, unless it's from the marketPlace contract.
    /// (Hopefully, we can prevent user accidents.)
    function() external payable {
        require(
            msg.sender == address(marketPlace)
        );
    }

    /// @notice Returns all the relevant information about a specific lambo.
    /// @param _id The ID of the lambo of interest.
    function getLambo(uint256 _id)
        external
        view
        returns (
        uint256 buildTime,
        uint256 attributes
    ) {
        Lambo storage kit = lambos[_id];

        buildTime = uint256(kit.buildTime);
        attributes = kit.attributes;
    }
    /// @notice Returns all the relevant information about a specific lambo.
    /// @param _id The ID of the lambo of interest.
    function getLamboAttributes(uint256 _id)
        external
        view
        returns (
        uint256 attributes
    ) {
        Lambo storage kit = lambos[_id];
        attributes = kit.attributes;
        return attributes;
    }
    
    /// @notice Returns all the relevant information about a specific lambo.
    /// @param _id The ID of the lambo of interest.
    function getLamboModel(uint256 _id)
        external
        view
        returns (
        uint64 model
    ) {
        Lambo storage kit = lambos[_id];
        model = kit.model;
        return model;
    }
    /// @dev Override unpause so it requires all external contract addresses
    ///  to be set before contract can be unpaused. Also, we can't have
    ///  newContractAddress set either, because then the contract was upgraded.
    /// @notice This is public rather than external so we can call super.unpause
    ///  without using an expensive CALL.
    function unpause() public onlyCEO whenPaused {
        require(marketPlace != address(0));
        require(serviceStation != address(0));
        require(newContractAddress == address(0));

        // Actually unpause the contract.
        super.unpause();
    }

    // @dev Allows the CFO to capture the balance available to the contract.
    function withdrawBalance() external onlyCFO {
        uint256 balance = this.balance;
        cfoAddress.send(balance);
     
    }
}
/// @title EtherLambos: Collectible, tuneable, and super stylish lambos on the Ethereum blockchain.
/// @author Cryptoknights code adapted from Axiom Zen (https://www.axiomzen.co)
/// @dev The main EtherLambos contract, keeps track of lambos.
function EtherLambosCore() public {
    // Starts paused.
    paused = true;

    // the creator of the contract is the initial CEO
    ceoAddress = msg.sender;

    // the creator of the contract is also the initial COO
    cooAddress = msg.sender;

    // start with the car 0 
    _createLambo(uint256(-1), address(0),0);
}

/// @notice Creates the main EtherLambos smart contract instance.