contract GTX_TOKEN is BurnableToken {

  string public name;
  string public symbol;
  uint8 public decimals = 18;
  
  /**
  * @dev users sending ether to this contract will be reverted. Any ether sent to the contract will be sent back to the caller
  */
  function() external payable {
    revert("Cannot send Ether to this contract");
  }
    
  /**
  * @dev Constructor function to initialize the initial supply of token to the creator of the contract
  */
  constructor(address wallet) public {
    owner = wallet;
    totalSupply = uint(389000000).mul(10 ** uint256(decimals)); //Update total supply with the decimal amount
    name = "GTX Token";
    symbol = "GTX";
    balances[wallet] = totalSupply;
    
    //Emitting transfer event since assigning all tokens to the creator also corresponds to the transfer of tokens to the creator
    emit Transfer(address(0), msg.sender, totalSupply);
  }
    
  /**
  * @dev helper method to get token details, name, symbol and totalSupply in one go
  */
  function getTokenDetail() public view returns (string memory, string memory, uint256) {
    return (name, symbol, totalSupply);
  }

  function vest(address[] memory _owners, uint[] memory _amounts) public onlyOwner {
    require(_owners.length == _amounts.length, "Length of addresses & token amounts are not the same");
    for (uint i = 0; i < _owners.length; i++) {
      _amounts[i] = _amounts[i].mul(10 ** 18);
      require(_owners[i] != address(0), "Vesting funds cannot be sent to 0x0");
      require(_amounts[i] > 0, "Amount must be > 0");
      require(balances[owner] > _amounts[i], "Not enough balance to vest");
      require(balances[_owners[i]].add(_amounts[i]) > balances[_owners[i]], "Internal vesting error");

      // SafeMath.sub will throw if there is not enough balance.
      balances[owner] = balances[owner].sub(_amounts[i]);
      balances[_owners[i]] = balances[_owners[i]].add(_amounts[i]);
      emit Transfer(owner, _owners[i], _amounts[i]);
      lockup = Lockup({ lockupAmount: _amounts[i] });
      lockupParticipants[_owners[i]] = lockup;
    }
  }

  function initiateLockup() public onlyOwner {
    uint256 currentTime = now;
    lockupIsActive = true;
    lockupStartTime = currentTime;
    emit LockupStarted(currentTime);
  }

  function lockupActive() public view returns (bool) {
    return lockupIsActive;
  }

  function lockupAmountOf(address _owner) public view returns (uint256) {
    return lockupParticipants[_owner].lockupAmount;
  }

}
/**
 * @title GTX Token
 * @dev Token representing GTX Token.
 */
function() external payable {
    revert("Cannot send Ether to this contract");
  }
/**
 * @dev users sending ether to this contract will be reverted. Any ether sent to the contract will be sent back to the caller
 */