contract EtherLambosBase is EtherLambosAccessControl {
    /*** EVENTS ***/

    /// @dev The Build event is fired whenever a new car model is build by the COO
    event Build(address owner, uint256 lamboId, uint256 attributes);

    /// @dev Transfer event as defined in current draft of ERC721. Emitted every time a car
    ///  ownership is assigned, including builds.
    event Transfer(address from, address to, uint256 tokenId);

    event Tune(uint256 _newattributes, uint256 _tokenId);
    
    /*** DATA TYPES ***/

    /// @dev The main EtherLambos struct. Every car in EtherLambos is represented by a copy
    ///  of this structure, so great care was taken to ensure that it fits neatly into
    ///  exactly two 256-bit words. Note that the order of the members in this structure
    ///  is important because of the byte-packing rules used by Ethereum.
    ///  Ref: http://solidity.readthedocs.io/en/develop/miscellaneous.html
    struct Lambo {
        // sports-car attributes like max speed, weight etc. are stored here.
        // These attributes can be changed due to tuning/upgrades
        uint256 attributes;

        // The timestamp from the block when this car came was constructed.
        uint64 buildTime;
        
        // the Lambo model identifier
        uint64 model;

    }


    // An approximation of currently how many seconds are in between blocks.
    uint256 public secondsPerBlock = 15;

    /*** STORAGE ***/

    /// @dev An array containing the Lambo struct for all Lambos in existence. The ID
    ///  of each car is actually an index into this array. Note that 0 is invalid index.
    Lambo[] lambos;

    /// @dev A mapping from car IDs to the address that owns them. All cars have
    ///  some valid owner address.
    mapping (uint256 => address) public lamboIndexToOwner;

    // @dev A mapping from owner address to count of tokens that address owns.
    //  Used internally inside balanceOf() to resolve ownership count.
    mapping (address => uint256) ownershipTokenCount;

    /// @dev A mapping from LamboIDs to an address that has been approved to call
    ///  transferFrom(). Each Lambo can only have one approved address for transfer
    ///  at any time. A zero value means no approval is outstanding.
    mapping (uint256 => address) public lamboIndexToApproved;

    /// @dev The address of the MarketPlace contract that handles sales of Lambos. This
    ///  same contract handles both peer-to-peer sales as well as new model sales. 
    MarketPlace public marketPlace;
    ServiceStation public serviceStation;
    /// @dev Assigns ownership of a specific Lambo to an address.
    function _transfer(address _from, address _to, uint256 _tokenId) internal {
        // Since the number of lambos is capped to 2^32 we can't overflow this
        ownershipTokenCount[_to]++;
        // transfer ownership
        lamboIndexToOwner[_tokenId] = _to;
        // When creating new lambos _from is 0x0, but we can't account that address.
        if (_from != address(0)) {
            ownershipTokenCount[_from]--;
            // clear any previously approved ownership exchange
            delete lamboIndexToApproved[_tokenId];
        }
        // Emit the transfer event.
        Transfer(_from, _to, _tokenId);
    }

    /// @dev An internal method that creates a new lambo and stores it. This
    ///  method doesn't do any checking and should only be called when the
    ///  input data is known to be valid. Will generate both a Build event
    ///  and a Transfer event.
    /// @param _attributes The lambo's attributes.
    /// @param _owner The inital owner of this car, must be non-zero
    function _createLambo(
        uint256 _attributes,
        address _owner,
        uint64  _model
    )
        internal
        returns (uint)
    {

        
        Lambo memory _lambo = Lambo({
            attributes: _attributes,
            buildTime: uint64(now),
            model:_model
        });
        uint256 newLamboId = lambos.push(_lambo) - 1;

        // It's probably never going to happen, 4 billion cars is A LOT, but
        // let's just be 100% sure we never let this happen.
        require(newLamboId == uint256(uint32(newLamboId)));

        // emit the build event
        Build(
            _owner,
            newLamboId,
            _lambo.attributes
        );

        // This will assign ownership, and also emit the Transfer event as
        // per ERC721 draft
        _transfer(0, _owner, newLamboId);

        return newLamboId;
    }
     /// @dev An internal method that tunes an existing lambo. This
    ///  method doesn't do any checking and should only be called when the
    ///  input data is known to be valid. Will generate a Tune event
    /// @param _newattributes The lambo's new attributes.
    /// @param _tokenId The car to be tuned.
    function _tuneLambo(
        uint256 _newattributes,
        uint256 _tokenId
    )
        internal
    {
        lambos[_tokenId].attributes=_newattributes;
     
        // emit the tune event
        Tune(
            _tokenId,
            _newattributes
        );

    }
    // Any C-level can fix how many seconds per blocks are currently observed.
    function setSecondsPerBlock(uint256 secs) external onlyCLevel {
        //require(secs < cooldowns[0]);
        secondsPerBlock = secs;
    }
}
/// @title Base contract for EtherLambos. Holds all common structs, events and base variables.
/// @author Axiom Zen (https://www.axiomzen.co) adapted by Kenny Bania
/// @dev ...
function _transfer(address _from, address _to, uint256 _tokenId) internal {
    // Since the number of lambos is capped to 2^32 we can't overflow this
    ownershipTokenCount[_to]++;
    // transfer ownership
    lamboIndexToOwner[_tokenId] = _to;
    // When creating new lambos _from is 0x0, but we can't account that address.
    if (_from != address(0)) {
        ownershipTokenCount[_from]--;
        // clear any previously approved ownership exchange
        delete lamboIndexToApproved[_tokenId];
    }
    // Emit the transfer event.
    Transfer(_from, _to, _tokenId);
}

/// @dev Assigns ownership of a specific Lambo to an address.