contract CollectibleMinting is CollectibleBase, OperationalControl {

    uint256 public rewardsRedeemed = 0;

    /// @dev Counts the number of promo collectibles that can be made per-team
    uint256[31]  public promoCreatedCount;
    
    /// @dev Counts the number of seed collectibles that can be made in total
    uint256 public seedCreatedCount;

    /// @dev Bool to toggle batch support
    bool public isBatchSupported = true;
    
    /// @dev A mapping of contracts that can trigger functions
    mapping (address => bool) public contractsApprovedList;
    
    /**
     * @dev        Helps to toggle batch supported flag
     * @param      _flag  The flag
     */
    function updateBatchSupport(bool _flag) public onlyManager {
        isBatchSupported = _flag;
    }

    modifier canCreate() { 
        require (contractsApprovedList[msg.sender] || 
            msg.sender == managerPrimary ||
            msg.sender == managerSecondary); 
        _; 
    }
    
    /**
     * @dev Add an address to the Approved List
     * @param _newAddress   The new address to be approved for interaction with the contract
     */
    function addToApproveList(address _newAddress) public onlyManager {
        
        require (!contractsApprovedList[_newAddress]);
        contractsApprovedList[_newAddress] = true;
    }

    /**
     * @dev Remove an address from Approved List
     * @param _newAddress   The new address to be approved for interaction with the contract
     */
    function removeFromApproveList(address _newAddress) public onlyManager {
        require (contractsApprovedList[_newAddress]);
        delete contractsApprovedList[_newAddress];
    }

    
    /**
     * @dev Generates promo collectibles. Only callable by Game Master, with isAttached as 0.
     * @notice The generation of an asset if limited via the generationSeasonController
     * @param _teamId           teamId of the asset/token/collectible
     * @param _posId            position of the asset/token/collectible
     * @param _attributes       attributes of asset/token/collectible
     * @param _owner            owner of asset/token/collectible
     * @param _gameId          mlb game Identifier
     * @param _playerOverrideId player override identifier
     * @param _mlbPlayerId      official mlb player identifier
     */
    function createPromoCollectible(
        uint8 _teamId,
        uint8 _posId,
        uint256 _attributes,
        address _owner,
        uint256 _gameId,
        uint256 _playerOverrideId,
        uint256 _mlbPlayerId)
        external
        canCreate
        whenNotPaused
        returns (uint256)
        {

        address nftOwner = _owner;
        if (nftOwner == address(0)) {
             nftOwner = managerPrimary;
        }

        if(allNFTs.length > 0) {
            promoCreatedCount[_teamId]++;
        }
        
        uint32 _sequenceId = getSequenceId(_teamId);
        
        uint256 assetDetails = uint256(uint64(now));
        assetDetails |= uint256(_sequenceId)<<64;
        assetDetails |= uint256(_teamId)<<96;
        assetDetails |= uint256(_posId)<<104;

        uint256[5] memory _nftData = [assetDetails, _attributes, _gameId, _playerOverrideId, _mlbPlayerId];
        
        return _createNFTCollectible(_teamId, _attributes, nftOwner, 0, _nftData);
    }

    /**
     * @dev Generaes a new single seed Collectible, with isAttached as 0.
     * @notice Helps in creating seed collectible.The generation of an asset if limited via the generationSeasonController
     * @param _teamId           teamId of the asset/token/collectible
     * @param _posId            position of the asset/token/collectible
     * @param _attributes       attributes of asset/token/collectible
     * @param _owner            owner of asset/token/collectible
     * @param _gameId          mlb game Identifier
     * @param _playerOverrideId player override identifier
     * @param _mlbPlayerId      official mlb player identifier
     */
    function createSeedCollectible(
        uint8 _teamId,
        uint8 _posId,
        uint256 _attributes,
        address _owner,
        uint256 _gameId,
        uint256 _playerOverrideId,
        uint256 _mlbPlayerId)
        external
        canCreate
        whenNotPaused
        returns (uint256) {

        address nftOwner = _owner;
        
        if (nftOwner == address(0)) {
             nftOwner = managerPrimary;
        }
        
        seedCreatedCount++;
        uint32 _sequenceId = getSequenceId(_teamId);
        
        uint256 assetDetails = uint256(uint64(now));
        assetDetails |= uint256(_sequenceId)<<64;
        assetDetails |= uint256(_teamId)<<96;
        assetDetails |= uint256(_posId)<<104;

        uint256[5] memory _nftData = [assetDetails, _attributes, _gameId, _playerOverrideId, _mlbPlayerId];
        
        return _createNFTCollectible(_teamId, _attributes, nftOwner, 0, _nftData);
    }

    /**
     * @dev Generate new Reward Collectible and transfer it to the owner, with isAttached as 0.
     * @notice Helps in redeeming the Rewards using our Oracle. Creates & transfers the asset to the redeemer (_owner)
     * The generation of an asset if limited via the generationSeasonController
     * @param _teamId           teamId of the asset/token/collectible
     * @param _posId            position of the asset/token/collectible
     * @param _attributes       attributes of asset/token/collectible
     * @param _owner            owner (redeemer) of asset/token/collectible
     * @param _gameId           mlb game Identifier
     * @param _playerOverrideId player override identifier
     * @param _mlbPlayerId      official mlb player identifier
     */
    function createRewardCollectible (
        uint8 _teamId,
        uint8 _posId,
        uint256 _attributes,
        address _owner,
        uint256 _gameId,
        uint256 _playerOverrideId,
        uint256 _mlbPlayerId)
        external
        canCreate
        whenNotPaused
        returns (uint256) {

        address nftOwner = _owner;
        
        if (nftOwner == address(0)) {
             nftOwner = managerPrimary;
        }
        
        rewardsRedeemed++;
        uint32 _sequenceId = getSequenceId(_teamId);
        
        uint256 assetDetails = uint256(uint64(now));
        assetDetails |= uint256(_sequenceId)<<64;
        assetDetails |= uint256(_teamId)<<96;
        assetDetails |= uint256(_posId)<<104;

        uint256[5] memory _nftData = [assetDetails, _attributes, _gameId, _playerOverrideId, _mlbPlayerId];
        
        return _createNFTCollectible(_teamId, _attributes, nftOwner, 0, _nftData);
    }

    /**
     * @dev Generate new ETH Card Collectible, with isAttached as 2.
     * @notice Helps to generate Collectibles/Tokens/Asset and transfer to ETH Cards,
     * which can be redeemed using our web-app.The generation of an asset if limited via the generationSeasonController
     * @param _teamId           teamId of the asset/token/collectible
     * @param _posId            position of the asset/token/collectible
     * @param _attributes       attributes of asset/token/collectible
     * @param _owner            owner of asset/token/collectible
     * @param _gameId           mlb game Identifier
     * @param _playerOverrideId player override identifier
     * @param _mlbPlayerId      official mlb player identifier
     */
    function createETHCardCollectible (
        uint8 _teamId,
        uint8 _posId,
        uint256 _attributes,
        address _owner,
        uint256 _gameId,
        uint256 _playerOverrideId,
        uint256 _mlbPlayerId)
        external
        canCreate
        whenNotPaused
        returns (uint256) {

        address nftOwner = _owner;
        
        if (nftOwner == address(0)) {
             nftOwner = managerPrimary;
        }
        
        rewardsRedeemed++;
        uint32 _sequenceId = getSequenceId(_teamId);
        
        uint256 assetDetails = uint256(uint64(now));
        assetDetails |= uint256(_sequenceId)<<64;
        assetDetails |= uint256(_teamId)<<96;
        assetDetails |= uint256(_posId)<<104;

        uint256[5] memory _nftData = [assetDetails, _attributes, _gameId, _playerOverrideId, _mlbPlayerId];
        
        return _createNFTCollectible(_teamId, _attributes, nftOwner, 2, _nftData);
    }
}
/* Handles creating new Collectibles for promo and seed.
 * @title CollectibleMinting Minting
 * @author Fazri Zubair & Farhan Khwaja (Lucid Sight, Inc.)
 * Inspired and adapted from KittyCore.sol created by Axiom Zen
 * Ref: ETH Contract - 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d
 */
function removeFromApproveList(address _newAddress) public onlyManager {
    require (contractsApprovedList[_newAddress]);
    delete contractsApprovedList[_newAddress];
}

/**
 * @dev Remove an address from Approved List
 * @param _newAddress   The new address to be approved for interaction with the contract
 */