contract FXT is MiniMeToken, Blocked {
  bool public sudoEnabled = true;

  modifier onlySudoEnabled() {
    require(sudoEnabled);
    _;
  }

  modifier onlyNotBlocked(address _addr) {
    require(!blocked[_addr]);
    _;
  }

  event SudoEnabled(bool _sudoEnabled);

  function FXT(address _tokenFactory) MiniMeToken(
    _tokenFactory,
    0x0,                  // no parent token
    0,                    // no snapshot block number from parent
    "FuzeX Token",        // Token name
    18,                   // Decimals
    "FXT",                // Symbol
    false                 // Enable transfers
  ) public {}

  /**
   * @dev transfer FuzeX token to `_to` with amount of `_amount`.
   * Only not blocked user can transfer.
   */
  function transfer(address _to, uint256 _amount) public onlyNotBlocked(msg.sender) returns (bool success) {
    return super.transfer(_to, _amount);
  }

  function transferFrom(address _from, address _to, uint256 _amount) public onlyNotBlocked(_from) returns (bool success) {
    return super.transferFrom(_from, _to, _amount);
  }

  // Below 4 functions is only activated by `sudoEnabled`
  // TODO: 3 sudo levels

  function generateTokens(address _owner, uint _amount) public onlyController onlySudoEnabled returns (bool) {
    return super.generateTokens(_owner, _amount);
  }

  function destroyTokens(address _owner, uint _amount) public onlyController onlySudoEnabled returns (bool) {
    return super.destroyTokens(_owner, _amount);
  }

  function blockAddress(address _addr) public onlyController onlySudoEnabled {
    super.blockAddress(_addr);
  }

  function unblockAddress(address _addr) public onlyController onlySudoEnabled {
    super.unblockAddress(_addr);
  }

  function enableSudo(bool _sudoEnabled) public onlyController {
    sudoEnabled = _sudoEnabled;
    SudoEnabled(_sudoEnabled);
  }

  // byList functions

  function generateTokensByList(address[] _owners, uint[] _amounts) public onlyController onlySudoEnabled returns (bool) {
    require(_owners.length == _amounts.length);

    for(uint i = 0; i < _owners.length; i++) {
      generateTokens(_owners[i], _amounts[i]);
    }

    return true;
  }
}
/**
 * @title FXT
 * @dev FXT is ERC20 token contract, inheriting MiniMeToken
 */
function transfer(address _to, uint256 _amount) public onlyNotBlocked(msg.sender) returns (bool success) {
  return super.transfer(_to, _amount);
}

/**
 * @dev transfer FuzeX token to `_to` with amount of `_amount`.
 * Only not blocked user can transfer.
 */