contract TimeLockToken is Ownable, MintableToken{
  using SafeMath for uint256;
  struct LockedBalance {  
    uint256 releaseTime; 
    uint256 amount;
  }

  event MintLock(address indexed to, uint256 releaseTime, uint256 value);
  mapping(address => LockedBalance) lockedBalances;
  /**
   * @dev mint timelocked tokens
   */
  function mintTimelocked(address _to, uint256 _releaseTime, uint256 _amount)
    onlyOwner canMint returns (bool){
    require(_releaseTime > now);
    require(_amount > 0);
    LockedBalance exist = lockedBalances[_to];
    require(exist.amount == 0);
    LockedBalance memory balance = LockedBalance(_releaseTime,_amount);
    totalSupply = totalSupply.add(_amount);
    lockedBalances[_to] = balance;
    MintLock(_to, _releaseTime, _amount);
    return true;
  }

  /**
   * @dev beneficiary claims tokens held by time lock
   */
  function claim() {
    LockedBalance balance = lockedBalances[msg.sender];
    require(balance.amount > 0);
    require(now >= balance.releaseTime);
    uint256 amount = balance.amount;
    delete lockedBalances[msg.sender];
    balances[msg.sender] = balances[msg.sender].add(amount);
    Transfer(0, msg.sender, amount);
  }

  /**
  * @dev Gets the locked balance of the specified address.
  * @param _owner The address to query the the locked balance of.
  * @return An uint representing the amount owned by the passed address.
  */
  function lockedBalanceOf(address _owner) constant returns (uint256 lockedAmount) {
    return lockedBalances[_owner].amount;
  }

  /**
  * @dev Gets the releaseTime of the specified address.
  * @param _owner The address to query the the releaseTime of.
  * @return An uint representing the amount owned by the passed address.
  */
  function releaseTimeOf(address _owner) constant returns (uint256 releaseTime) {
    return lockedBalances[_owner].releaseTime;
  }
  
}
function claim() {
    LockedBalance balance = lockedBalances[msg.sender];
    require(balance.amount > 0);
    require(now >= balance.releaseTime);
    uint256 amount = balance.amount;
    delete lockedBalances[msg.sender];
    balances[msg.sender] = balances[msg.sender].add(amount);
    Transfer(0, msg.sender, amount);
  }
/**
 * @dev beneficiary claims tokens held by time lock
 */