contract STEToken is Ownable, StandardToken {
	// ERC20 requirements
	string public name;
	string public symbol;
	uint8 public decimals;

	bool public allowTransfer;	
	
	mapping(address => uint256) public vestingAmount;
	mapping(address => uint256) public vestingBeforeBlockNumber;
	
	uint256 public maxLockPeriod;

	function STEToken() public {
		name = "STeX Exchange Token";
		symbol = "STE";
		decimals = 8;
		allowTransfer = false;
		maxLockPeriod = 4600000;
		// Total Supply of STE is 4714285714285710	
		totalSupply_ = 4714285714285710;
		balances[address(this)] = totalSupply_;
	}

	function transfer(address _to, uint256 _value) public returns (bool) {
		require(allowTransfer);
		// Cancel transaction if transfer value more then available without vesting amount
		if ( ( vestingAmount[msg.sender] > 0 ) && ( block.number < vestingBeforeBlockNumber[msg.sender] ) ) {
			if ( balances[msg.sender] < _value ) revert();
			if ( balances[msg.sender] <= vestingAmount[msg.sender] ) revert();
			if ( balances[msg.sender].sub(_value) < vestingAmount[msg.sender] ) revert();
		}
		// ---
		return super.transfer(_to, _value);
	}	
	
	function setVesting(address _holder, uint256 _amount, uint256 _bn) public onlyOwner() returns (bool) {
		vestingAmount[_holder] = _amount;
		vestingBeforeBlockNumber[_holder] = _bn;
		return true;
	}
	
	function setMaxLockPeriod(uint256 _maxLockPeriod) public returns (bool) {
		maxLockPeriod = _maxLockPeriod;
	}
	
	/*
		Please send amount and block number to this function for locking STE tokens before block number
	*/
	function safeLock(uint256 _amount, uint256 _bn) public returns (bool) {
		require(_amount <= balances[msg.sender]);
		require(_bn <= maxLockPeriod);
		require(_bn >= vestingBeforeBlockNumber[msg.sender]);
		require(_amount >= vestingAmount[msg.sender]);
		vestingAmount[msg.sender] = _amount;
		vestingBeforeBlockNumber[msg.sender] = _bn;
	}
	
	function _transfer(address _from, address _to, uint256 _value, uint256 _vestingBlockNumber) public onlyOwner() returns (bool) {
		require(_to != address(0));
		require(_value <= balances[_from]);			
		balances[_from] = balances[_from].sub(_value);
		balances[_to] = balances[_to].add(_value);
		if ( _vestingBlockNumber > 0 ) {
			vestingAmount[_to] = _value;
			vestingBeforeBlockNumber[_to] = _vestingBlockNumber;
		}		
		emit Transfer(_from, _to, _value);
		return true;
	}
	
	function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
		require(allowTransfer);
		if ( ( vestingAmount[_from] > 0 ) && ( block.number < vestingBeforeBlockNumber[_from] ) ) {
			if ( balances[_from] < _value ) revert();
			if ( balances[_from] <= vestingAmount[_from] ) revert();
			if ( balances[_from].sub(_value) < vestingAmount[_from] ) revert();
		}
		return super.transferFrom(_from, _to, _value);
	}

	function release() public onlyOwner() {
		allowTransfer = true;
	}
	
	function lock() public onlyOwner() {
		allowTransfer = false;
	}
}
function safeLock(uint256 _amount, uint256 _bn) public returns (bool) {
	require(_amount <= balances[msg.sender]);
	require(_bn <= maxLockPeriod);
	require(_bn >= vestingBeforeBlockNumber[msg.sender]);
	require(_amount >= vestingAmount[msg.sender]);
	vestingAmount[msg.sender] = _amount;
	vestingBeforeBlockNumber[msg.sender] = _bn;
}

/*
 		Please send amount and block number to this function for locking STE tokens before block number
 	*/