contract PixelOwnership is PixelBase, ERC721 {

    /// @notice Name and symbol of the non fungible token, as defined in ERC721.
    string public constant name = "PixelCoins";
    string public constant symbol = "PXL";


    bytes4 constant InterfaceSignature_ERC165 =
        bytes4(keccak256('supportsInterface(bytes4)'));

    bytes4 constant InterfaceSignature_ERC721 =
        bytes4(keccak256('name()')) ^
        bytes4(keccak256('symbol()')) ^
        bytes4(keccak256('totalSupply()')) ^
        bytes4(keccak256('balanceOf(address)')) ^
        bytes4(keccak256('ownerOf(uint256)')) ^
        bytes4(keccak256('approve(address,uint256)')) ^
        bytes4(keccak256('transfer(address,uint256)')) ^
        bytes4(keccak256('transferFrom(address,address,uint256)')) ^
        bytes4(keccak256('tokensOfOwner(address)')) ^
        bytes4(keccak256('tokenMetadata(uint256,string)'));


    string public metaBaseUrl = "https://pixelcoins.io/meta/";


    /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165).
    ///  Returns true for any standardized interfaces implemented by this contract. We implement
    ///  ERC-165 (obviously!) and ERC-721.
    function supportsInterface(bytes4 _interfaceID) external view returns (bool) {
        return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721));
    }

    /// @notice Returns the number ofd Pixels owned by a specific address.
    /// @param _owner The owner address to check.
    /// @dev Required for ERC-721 compliance
    function balanceOf(address _owner) public view returns (uint256 count) {
        return ownershipTokenCount[_owner];
    }

    /// @notice Transfers a Pixel to another address. If transferring to a smart
    ///  contract be VERY CAREFUL to ensure that it is aware of ERC-721 (or
    ///  PixelCoins specifically) or your Pixel may be lost forever. Seriously.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _tokenId The ID of the Pixel to transfer.
    /// @dev Required for ERC-721 compliance.
    function transfer(
        address _to,
        uint256 _tokenId
    )
        external
    {
        // Safety check to prevent against an unexpected 0x0 default.
        require(_to != address(0));
        // Disallow transfers to this contract to prevent accidental misuse.
        // The contract should never own any pixel (except very briefly
        // after a gen0 cat is created and before it goes on auction).
        require(_to != address(this));

        // You can only send your own pixel.
        require(_owns(msg.sender, _tokenId));
        // address is not currently managed by the contract (it is in an auction)
        require(pixelIndexToApproved[_tokenId] != address(this));

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

    /// @notice Grant another address the right to transfer a specific pixel via
    ///  transferFrom(). This is the preferred flow for transfering NFTs to contracts.
    /// @param _to The address to be granted transfer approval. Pass address(0) to
    ///  clear all approvals.
    /// @param _tokenId The ID of the pixel that can be transferred if this call succeeds.
    /// @dev Required for ERC-721 compliance.
    function approve(
        address _to,
        uint256 _tokenId
    )
        external
    {
        // Only an owner can grant transfer approval.
        require(_owns(msg.sender, _tokenId));
        // address is not currently managed by the contract (it is in an auction)
        require(pixelIndexToApproved[_tokenId] != address(this));

        // Register the approval (replacing any previous approval).
        pixelIndexToApproved[_tokenId] = _to;

        // Emit approval event.
        Approval(msg.sender, _to, _tokenId);
    }

    /// @notice Transfer a Pixel owned by another address, for which the calling address
    ///  has previously been granted transfer approval by the owner.
    /// @param _from The address that owns the pixel to be transfered.
    /// @param _to The address that should take ownership of the Pixel. Can be any address,
    ///  including the caller.
    /// @param _tokenId The ID of the Pixel to be transferred.
    /// @dev Required for ERC-721 compliance.
    function transferFrom(
        address _from,
        address _to,
        uint256 _tokenId
    )
        external
    {
        // Safety check to prevent against an unexpected 0x0 default.
        require(_to != address(0));
        // Disallow transfers to this contract to prevent accidental misuse.
        // The contract should never own anyd Pixels (except very briefly
        // after a gen0 cat is created and before it goes on auction).
        require(_to != address(this));
        // Check for approval and valid ownership
        require(_approvedFor(msg.sender, _tokenId));
        require(_owns(_from, _tokenId));

        // Reassign ownership (also clears pending approvals and emits Transfer event).
        _transfer(_from, _to, _tokenId);
    }

    /// @notice Returns the total number of pixels currently in existence.
    /// @dev Required for ERC-721 compliance.
    function totalSupply() public view returns (uint) {
        return WIDTH * HEIGHT;
    }

    /// @notice Returns the address currently assigned ownership of a given Pixel.
    /// @dev Required for ERC-721 compliance.
    function ownerOf(uint256 _tokenId)
        external
        view
        returns (address owner)
    {
        owner = pixelIndexToOwner[_tokenId];
        require(owner != address(0));
    }

    /// @notice Returns the addresses currently assigned ownership of the given pixel area.
    function ownersOfArea(uint256 x, uint256 y, uint256 x2, uint256 y2) external view returns (address[] result) {
        require(x2 > x && y2 > y);
        require(x2 <= WIDTH && y2 <= HEIGHT);
        result = new address[]((y2 - y) * (x2 - x));

        uint256 r = 0;
        for (uint256 i = y; i < y2; i++) {
            uint256 tokenId = i * WIDTH;
            for (uint256 j = x; j < x2; j++) {
                result[r] = pixelIndexToOwner[tokenId + j];
                r++;
            }
        }
    }

    /// @notice Returns a list of all Pixel IDs assigned to an address.
    /// @param _owner The owner whosed Pixels we are interested in.
    /// @dev This method MUST NEVER be called by smart contract code. First, it's fairly
    ///  expensive (it walks the entire Pixel array looking for pixels belonging to owner),
    ///  but it also returns a dynamic array, which is only supported for web3 calls, and
    ///  not contract-to-contract calls.
    function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) {
        uint256 tokenCount = balanceOf(_owner);

        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            uint256 totalPixels = totalSupply();
            uint256 resultIndex = 0;

            // We count on the fact that all pixels have IDs starting at 0 and increasing
            // sequentially up to the totalCat count.
            uint256 pixelId;

            for (pixelId = 0; pixelId <= totalPixels; pixelId++) {
                if (pixelIndexToOwner[pixelId] == _owner) {
                    result[resultIndex] = pixelId;
                    resultIndex++;
                }
            }

            return result;
        }
    }

    // Taken from https://ethereum.stackexchange.com/a/10929
    function uintToString(uint v) constant returns (string str) {
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = byte(48 + remainder);
        }
        bytes memory s = new bytes(i);
        for (uint j = 0; j < i; j++) {
            s[j] = reversed[i - 1 - j];
        }
        str = string(s);
    }

    // Taken from https://ethereum.stackexchange.com/a/10929
    function appendUintToString(string inStr, uint v) constant returns (string str) {
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = byte(48 + remainder);
        }
        bytes memory inStrb = bytes(inStr);
        bytes memory s = new bytes(inStrb.length + i);
        uint j;
        for (j = 0; j < inStrb.length; j++) {
            s[j] = inStrb[j];
        }
        for (j = 0; j < i; j++) {
            s[j + inStrb.length] = reversed[i - 1 - j];
        }
        str = string(s);
    }

    function setMetaBaseUrl(string _metaBaseUrl) external onlyAuthority {
        metaBaseUrl = _metaBaseUrl;
    }

    /// @notice Returns a URI pointing to a metadata package for this token conforming to
    ///  ERC-721 (https://github.com/ethereum/EIPs/issues/721)
    /// @param _tokenId The ID number of the Pixel whose metadata should be returned.
    function tokenMetadata(uint256 _tokenId) external view returns (string infoUrl) {
        return appendUintToString(metaBaseUrl, _tokenId);
    }
}
/// @title The facet of the PixelCoins core contract that manages ownership, ERC-721 (draft) compliant.
/// @author Oliver Schneider <info@pixelcoins.io> (https://pixelcoins.io), based on Axiom Zen (https://www.axiomzen.co)
/// @dev Ref: https://github.com/ethereum/EIPs/issues/721
///  See the PixelCore contract documentation to understand how the various contract facets are arranged.
function ownerOf(uint256 _tokenId)
    external
    view
    returns (address owner)
{
    owner = pixelIndexToOwner[_tokenId];
    require(owner != address(0));
}

/// @notice Returns the address currently assigned ownership of a given Pixel.
/// @dev Required for ERC-721 compliance.