contract TokenLock {
    using SafeMath for uint256;
	InseeCoin  public  ISC;     // The InSeeCoin token itself

    /**
     * Next time lock ID to be used.
     */
    uint256 private nextLockID = 0;

    /**
     * Maps time lock ID to TokenTimeLockInfo structure encapsulating time lock
     * information.
     */
    mapping (uint256 => TokenTimeLockInfo) public locks;

    /**
     * Encapsulates information abount time lock.
     */
    struct TokenTimeLockInfo {

        /**
         * Beneficiary to receive tokens once they are unlocked.
         */
        address beneficiary;

        /**
         * Amount of locked tokens.
         */
        uint256 amount;

        /**
         * Unlock time.
         */
        uint256 unlockTime;
    }

    /**
     * Logged when tokens were time locked.
     *
     * @param id time lock ID
     * @param beneficiary beneficiary to receive tokens once they are unlocked
     * @param amount amount of locked tokens
     * @param lockTime unlock time
     */
    event Lock (uint256 indexed id, address indexed beneficiary,uint256 amount, uint256 lockTime);
      /**
     * Logged when tokens were unlocked and sent to beneficiary.
     *
     * @param id time lock ID
     * @param beneficiary beneficiary to receive tokens once they are unlocked
     * @param amount amount of locked tokens
     * @param unlockTime unlock time
     */
    event Unlock (uint256 indexed id, address indexed beneficiary,uint256 amount, uint256 unlockTime);

	function TokenLock(InseeCoin isc) public {
        assert(address(isc) != address(0));

        ISC = isc;
	}

	/**
     * Lock given amount of given EIP-20 tokens until given time arrives, after
     * this time allow the tokens to be transferred to given beneficiary.  This
     * contract should be allowed to transfer at least given amount of tokens
     * from msg.sender.
     *
     * @param _beneficiary beneficiary to receive tokens after unlock time
     * @param _amount amount of tokens to be locked
     * @param _lockTime unlock time
     *
     * @return time lock ID
     */
    function lock (
      address _beneficiary, uint256 _amount,
        uint256 _lockTime) public returns (uint256) {
        require (_amount > 0);
        require (_lockTime > 0);

        nextLockID = nextLockID.add(1);
        uint256 id = nextLockID;

        TokenTimeLockInfo storage lockInfo = locks [id];
        require (lockInfo.beneficiary == 0x0);
        require (lockInfo.amount == 0);
        require (lockInfo.unlockTime == 0);

        lockInfo.beneficiary = _beneficiary;
        lockInfo.amount = _amount;
        lockInfo.unlockTime =  now.add(_lockTime);

        emit Lock (id, _beneficiary, _amount, _lockTime);

        require (ISC.transferFrom (msg.sender, this, _amount));

        return id;
    }


    /**
     * Unlock tokens locked under time lock with given ID and transfer them to
     * corresponding beneficiary.
     *
     * @param _id time lock ID to unlock tokens locked under
     */
    function unlock (uint256 _id) public {
        TokenTimeLockInfo memory lockInfo = locks [_id];
        delete locks [_id];

        require (lockInfo.amount > 0);
        require (lockInfo.unlockTime <= block.timestamp);

        emit Unlock (_id, lockInfo.beneficiary, lockInfo.amount, lockInfo.unlockTime);

        require (
            ISC.transfer (
                lockInfo.beneficiary, lockInfo.amount));
    }


}
function unlock (uint256 _id) public {
    TokenTimeLockInfo memory lockInfo = locks [_id];
    delete locks [_id];

    require (lockInfo.amount > 0);
    require (lockInfo.unlockTime <= block.timestamp);

    emit Unlock (_id, lockInfo.beneficiary, lockInfo.amount, lockInfo.unlockTime);

    require (
        ISC.transfer (
            lockInfo.beneficiary, lockInfo.amount));
}

/**
 * Unlock tokens locked under time lock with given ID and transfer them to
 * corresponding beneficiary.
 *
 * @param _id time lock ID to unlock tokens locked under
 */