contract TurexToken is BurnableToken, Ownable {

  string constant public name = "Turex"; 
  string constant public symbol = "TUR"; 
  uint256 constant public decimals = 18; 
  uint256 constant public initial = 5 ether * 10 ** 6; 

  mapping (address=>bool) public allowedAddresses;
  bool public unfrozen;

  event Unfreeze();

  constructor() public {
    _mint(msg.sender, initial);
  }


  function allowTransfer(address _for) public onlyOwner returns (bool) {
    allowedAddresses[_for] = true;
    return true;
  }

  function disableTransfer(address _for) public onlyOwner returns (bool) {
    allowedAddresses[_for] = false;
    return true;
  }
  
  modifier isTrasferAllowed(address a, address b) {
    require(unfrozen || allowedAddresses[a] || allowedAddresses[b]);
    _;
  }


  function unfreeze() public onlyOwner returns (bool) {
    require(!unfrozen);
    unfrozen = true;
    emit Unfreeze();
    return true;
  }


  /// @dev Overrides burnable interface to prevent interaction before finalization
  function burn(uint256 _value) public isTrasferAllowed(msg.sender, address(0x0)) {
    super.burn(_value);
  }

  /// @dev Overrides burnable interface to prevent interaction before finalization
  function burnFrom(address _from, uint256 _value) isTrasferAllowed(_from, address(0x0)) public {
    super.burnFrom(_from, _value);
  }

  /// @dev Overrides ERC20 interface to prevent interaction before finalization
  function transferFrom(address _from, address _to, uint256 _value) public isTrasferAllowed(_from, _to) returns (bool) {
    return super.transferFrom(_from, _to, _value);
  }

  /// @dev Overrides ERC20 interface to prevent interaction before finalization
  function transfer(address _to, uint256 _value) public isTrasferAllowed(msg.sender, _to) returns (bool) {
    return super.transfer(_to, _value);
  }

  /// @dev Overrides ERC20 interface to prevent interaction before finalization
  function approve(address _spender, uint256 _value) public isTrasferAllowed(msg.sender, _spender) returns (bool) {
    return super.approve(_spender, _value);
  }

  /// @dev Overrides ERC20 interface to prevent interaction before finalization
  function increaseApproval(address _spender, uint256 _addedValue) public isTrasferAllowed(msg.sender, _spender) returns (bool) {
    return super.increaseApproval(_spender, _addedValue);
  }

  /// @dev Overrides ERC20 interface to prevent interaction before finalization
  function decreaseApproval(address _spender, uint256 _subtractedValue) public isTrasferAllowed(msg.sender, _spender) returns (bool) {
    return super.decreaseApproval(_spender, _subtractedValue);
  }
}
function transfer(address _to, uint256 _value) public isTrasferAllowed(msg.sender, _to) returns (bool) {
  return super.transfer(_to, _value);
}

/// @dev Overrides ERC20 interface to prevent interaction before finalization