contract OwnerRegistry {
  using SafeMath for uint256;

  /////////
  // Events
  /////////

  event CardCreated(
    bytes32 indexed _sig,
    uint256 _numAdded
  );

  event CardsTransferred(
    bytes32 indexed _sig,
    address indexed _oldOwner,
    address indexed _newOwner,
    uint256 _count
  );

  ////////
  // State
  ////////

  bytes32[] _allSigs;
  mapping(address => mapping(bytes32 => uint256)) _ownerToSigToCount;
  mapping(bytes32 => uint256) _sigToCount;

  ////////////////
  // Admin actions
  ////////////////

  function addCardToRegistry(address owner, bytes32 sig, uint256 numToAdd) internal {
    // Only allow adding cards that haven't already been added
    require(_sigToCount[sig] == 0);

    _allSigs.push(sig);
    _ownerToSigToCount[owner][sig] = numToAdd;
    _sigToCount[sig] = numToAdd;

    emit CardCreated(sig, numToAdd);
  }

  /////////////
  // User views
  /////////////

  function getAllSigs() public view returns (bytes32[]) {
    return _allSigs;
  }

  function getNumSigsOwned(bytes32 sig) public view returns (uint256) {
    return _ownerToSigToCount[msg.sender][sig];
  }

  function getNumSigs(bytes32 sig) public view returns (uint256) {
    return _sigToCount[sig];
  }

  ///////////////////
  // Transfer actions
  ///////////////////

  function registryTransfer(address oldOwner, address newOwner, bytes32 sig, uint256 count) internal {
    // Must be transferring at least one card!
    require(count > 0);

    // Don't allow a transfer when the old owner doesn't enough of the card
    require(_ownerToSigToCount[oldOwner][sig] >= count);

    _ownerToSigToCount[oldOwner][sig] = _ownerToSigToCount[oldOwner][sig].sub(count);
    _ownerToSigToCount[newOwner][sig] = _ownerToSigToCount[newOwner][sig].add(count);

    emit CardsTransferred(sig, oldOwner, newOwner, count);
  }
}
function registryTransfer(address oldOwner, address newOwner, bytes32 sig, uint256 count) internal {
  // Must be transferring at least one card!
  require(count > 0);

  // Don't allow a transfer when the old owner doesn't enough of the card
  require(_ownerToSigToCount[oldOwner][sig] >= count);

  _ownerToSigToCount[oldOwner][sig] = _ownerToSigToCount[oldOwner][sig].sub(count);
  _ownerToSigToCount[newOwner][sig] = _ownerToSigToCount[newOwner][sig].add(count);

  emit CardsTransferred(sig, oldOwner, newOwner, count);
}

///////////////////