contract HeroToken is ERC721, DungeonStructs, Pausable, JointOwnable {

    /**
     * @dev The Mint event is fired whenever a new hero is created.
     */
    event Mint(address indexed owner, uint newTokenId, uint _genes);

    /**
     * @dev Transfer event as defined in current draft of ERC721. Emitted every time a token
     *  ownership is assigned, including token creation.
     */
    event Transfer(address indexed from, address indexed to, uint tokenId);

    /**
     * @dev Name of token.
     */
    string public constant name = "Hero";

    /**
     * @dev Symbol of token.
     */
    string public constant symbol = "HERO";

    /**
     * @dev An array containing the Hero struct, which contains all the heroes in existance.
     *  The ID for each hero is the index of this array.
     */
    Hero[] public heroes;

    /**
     * @dev A mapping from token IDs to the address that owns them.
     */
    mapping(uint => address) tokenIndexToOwner;

    /**
     * @dev A mapping from owner address to count of tokens that address owns.
     */
    mapping(address => uint) ownershipTokenCount;

    /**
     * Each non-fungible token owner can own more than one token at one time.
     * Because each token is referenced by its unique ID, however,
     * it can get difficult to keep track of the individual tokens that a user may own.
     * To do this, the contract keeps a record of the IDs of each token that each user owns.
     */
    mapping(address => uint[]) public ownerTokens;

    /**
     * @dev Returns the total number of tokens currently in existence.
     */
    function totalSupply() public view returns (uint) {
        return heroes.length;
    }

    /**
     * @dev Returns the number of tokens owned by a specific address.
     * @param _owner The owner address to check.
     */
    function balanceOf(address _owner) public view returns (uint) {
        return ownershipTokenCount[_owner];
    }

    /**
     * @dev Checks if a given address is the current owner of a particular token.
     * @param _claimant The address we are validating against.
     * @param _tokenId Token ID
     */
    function _owns(address _claimant, uint _tokenId) internal view returns (bool) {
        return tokenIndexToOwner[_tokenId] == _claimant;
    }

    /**
     * @dev Returns the address currently assigned ownership of a given token.
     */
    function ownerOf(uint _tokenId) external view returns (address) {
        require(tokenIndexToOwner[_tokenId] != address(0));

        return tokenIndexToOwner[_tokenId];
    }

    /**
     * @dev Assigns ownership of a specific token to an address.
     */
    function _transfer(address _from, address _to, uint _tokenId) internal {
        // Increment the ownershipTokenCount.
        ownershipTokenCount[_to]++;

        // Transfer ownership.
        tokenIndexToOwner[_tokenId] = _to;

        // Add the _tokenId to ownerTokens[_to]
        ownerTokens[_to].push(_tokenId);

        // When creating new token, _from is 0x0, but we can't account that address.
        if (_from != address(0)) {
            ownershipTokenCount[_from]--;

            // Remove the _tokenId from ownerTokens[_from]
            uint[] storage fromTokens = ownerTokens[_from];
            bool iFound = false;

            for (uint i = 0; i < fromTokens.length - 1; i++) {
                if (iFound) {
                    fromTokens[i] = fromTokens[i + 1];
                } else if (fromTokens[i] == _tokenId) {
                    iFound = true;
                    fromTokens[i] = fromTokens[i + 1];
                }
            }

            fromTokens.length--;
        }

        // Emit the Transfer event.
        Transfer(_from, _to, _tokenId);
    }

    /**
     * @dev External function to transfers a token to another address.
     * @param _to The address of the recipient, can be a user or contract.
     * @param _tokenId The ID of the token to transfer.
     */
    function transfer(address _to, uint _tokenId) whenNotPaused external {
        // Safety check to prevent against an unexpected 0x0 default.
        require(_to != address(0));

        // Disallow transfers to this contract to prevent accidental misuse.
        require(_to != address(this));

        // You can only send your own token.
        require(_owns(msg.sender, _tokenId));

        // Reassign ownership, clear pending approvals, emit Transfer event.
        _transfer(msg.sender, _to, _tokenId);
    }

    /**
     * @dev Get an array of IDs of each token that an user owns.
     */
    function getOwnerTokens(address _owner) external view returns(uint[]) {
        return ownerTokens[_owner];
    }

    /**
     * @dev An external function that creates a new hero and stores it,
     *  only contract owners can create new token.
     *  method doesn't do any checking and should only be called when the
     *  input data is known to be valid.
     * @param _genes The gene of the new hero.
     * @param _owner The inital owner of this hero.
     * @return The hero ID of the new hero.
     */
    function createHero(uint _genes, address _owner) eitherOwner external returns (uint) {
        // UPDATE STORAGE
        // Create a new hero.
        heroes.push(Hero(uint64(now), 0, 0, _genes));

        // Token id is the index in the storage array.
        uint newTokenId = heroes.length - 1;

        // Emit the token mint event.
        Mint(_owner, newTokenId, _genes);

        // This will assign ownership, and also emit the Transfer event.
        _transfer(0, _owner, newTokenId);

        return newTokenId;
    }

    /**
     * @dev The external function to set the hero genes by its ID,
     *  only contract owners can alter hero state.
     */
    function setHeroGenes(uint _id, uint _newGenes) eitherOwner tokenExists(_id) external {
        heroes[_id].genes = _newGenes;
    }

    /**
     * @dev Set the cooldownStartTime for the given hero. Also increments the cooldownIndex.
     */
    function triggerCooldown(uint _id) eitherOwner tokenExists(_id) external {
        Hero storage hero = heroes[_id];

        hero.cooldownStartTime = uint64(now);
        hero.cooldownIndex++;
    }


    /* ======== MODIFIERS ======== */

    /**
     * @dev Throws if _dungeonId is not created yet.
     */
    modifier tokenExists(uint _tokenId) {
        require(_tokenId < totalSupply());
        _;
    }

}
/**
 * @title The ERC-721 compliance token contract for the Hero tokens.
 * @dev See the DungeonStructs contract to see the details of the Hero token data structure.
 */
function setHeroGenes(uint _id, uint _newGenes) eitherOwner tokenExists(_id) external {
    heroes[_id].genes = _newGenes;
}

/**
 * @dev The external function to set the hero genes by its ID,
 *  only contract owners can alter hero state.
 */