contract Token is TokenLoggerCallback {

  string public constant name = "Digix Gold Token";
  string public constant symbol = "DGX";
  uint8 public constant decimals = 9;

  function Token(address _resolver) public
  {
    require(init(CONTRACT_INTERACTIVE_TOKEN, _resolver));
  }

  /// @notice show the total supply of gold tokens
  /// @return {
  ///    "totalSupply": "total number of tokens"
  /// }
  function totalSupply()
           constant
           public
           returns (uint256 _total_supply)
  {
    _total_supply = TokenInfoController(get_contract(CONTRACT_CONTROLLER_TOKEN_INFO)).get_total_supply();
  }

  /// @notice display balance of given account
  /// @param _owner the account to query
  /// @return {
  ///    "balance": "balance of the given account in nanograms"
  /// }
  function balanceOf(address _owner)
           constant
           public
           returns (uint256 balance)
  {
    balance = TokenInfoController(get_contract(CONTRACT_CONTROLLER_TOKEN_INFO)).get_balance(_owner);
  }

  /// @notice transfer amount to account
  /// @param _to account to send to
  /// @param _value the amount in nanograms to send
  /// @return {
  ///    "success": "returns true if successful"
  /// }
  function transfer(address _to, uint256 _value)
           public
           returns (bool success)
  {
    success =
      TokenTransferController(get_contract(CONTRACT_CONTROLLER_TOKEN_TRANSFER)).put_transfer(msg.sender, _to, 0x0, _value, false);
  }

  /// @notice transfer amount to account from account deducting from spender allowance
  /// @param _to account to send to
  /// @param _from account to send from
  /// @param _value the amount in nanograms to send
  /// @return {
  ///    "success": "returns true if successful"
  /// }
  function transferFrom(address _from, address _to, uint256 _value)
           public
           returns (bool success)
  {
    success =
      TokenTransferController(get_contract(CONTRACT_CONTROLLER_TOKEN_TRANSFER)).put_transfer(_from, _to, msg.sender,
                                                                             _value, true);
  }

  /// @notice implements transferAndCall() of ERC677
  /// @param _receiver the contract to receive the token
  /// @param _amount the amount of tokens to be transfered
  /// @param _data the data to be passed to the tokenFallback function of the receiving contract
  /// @return {
  ///    "success": "returns true if successful"
  /// }
  function transferAndCall(address _receiver, uint256 _amount, bytes32 _data)
           public
           returns (bool success)
  {
    transfer(_receiver, _amount);
    success = TokenReceiver(_receiver).tokenFallback(msg.sender, _amount, _data);
    require(success);
  }

  /// @notice approve given spender to transfer given amount this will set allowance to 0 if current value is non-zero
  /// @param _spender the account that is given an allowance
  /// @param _value the amount in nanograms to approve
  /// @return {
  ///   "success": "returns true if successful"
  /// }
  function approve(address _spender, uint256 _value)
           public
           returns (bool success)
  {
    success = TokenApprovalController(get_contract(CONTRACT_CONTROLLER_TOKEN_APPROVAL)).approve(msg.sender, _spender, _value);
  }

  /// @notice check the spending allowance of a given user from a given account
  /// @param _owner the account to spend from
  /// @param _spender the spender
  /// @return {
  ///    "remaining": "the remaining allowance in nanograms"
  /// }
  function allowance(address _owner, address _spender)
           constant
           public
           returns (uint256 remaining)
  {
    remaining = TokenInfoController(get_contract(CONTRACT_CONTROLLER_TOKEN_INFO)).get_allowance(_owner, _spender);
  }

}
/// @title DGX2.0 ERC-20 Token. ERC-677 is also implemented https://github.com/ethereum/EIPs/issues/677
/// @author Digix Holdings Pte Ltd
function transfer(address _to, uint256 _value)
         public
         returns (bool success)
{
  success =
    TokenTransferController(get_contract(CONTRACT_CONTROLLER_TOKEN_TRANSFER)).put_transfer(msg.sender, _to, 0x0, _value, false);
}

/// @notice transfer amount to account
/// @param _to account to send to
/// @param _value the amount in nanograms to send
/// @return {
///    "success": "returns true if successful"
/// }