contract ECOPLocker is owned{
    using SafeMath for uint256;

    uint256[] public MONTH_TIER = [132392,110363,110363,110363,7343,7343,7343,7343,7343,7343,7343,7343,7343];
    uint256 constant public TOTAL_AMOUNT = 529568*10**18;

    event CoinWithdrawn(address indexed addr, uint256 amount);

    address payable user_addr;

    IERC20 ecop;

    uint256 public withdraw_tokens;

    uint40 public online_time;

    constructor(address payable ecopContractAddress, address payable userAddress) public {

    	ecop = IERC20(ecopContractAddress);

	user_addr = userAddress;

	withdraw_tokens = 0;

	//init online time for 1 year later
        online_time = uint40(block.timestamp+365*86400);
    }

    function setOnlineTime(uint40 ts) onlyOwner public {

	online_time = ts;
    }

    function withdraw() public {

	require(msg.sender == user_addr, "only authorized user.");

	uint256 amount = this.getAvailableAmount();
	
        require(amount > 0, "No available coins.");

	uint256 ecop_balance = ecop.balanceOf(address(this));

        require(ecop_balance >= amount, "No ECOP left for withdrawing");

	ecop.transfer(msg.sender, amount);

	withdraw_tokens = withdraw_tokens.add(amount);

	emit CoinWithdrawn(msg.sender, amount);
    }

    /*
        Only external call
    */
    function getAvailableAmount() view external returns(uint256) {
	uint256 ts = block.timestamp;
	if(ts < online_time)
		return 0;
	uint256 time_span = ts - online_time;
	uint256 index = time_span.div(30*86400);
	uint256 amount = 0;
	for(uint256 i=0; i <= index; i++)
	{
		amount = amount.add(MONTH_TIER[i].mul(10**18));
	}
	if(amount > TOTAL_AMOUNT)
		amount = TOTAL_AMOUNT;
	if(amount < withdraw_tokens)
		amount = 0;
	else
		amount = amount.sub(withdraw_tokens);
	return amount;
    }

    function getContractInfo() view external returns(uint256 _total_amount, uint256 _withdraw_tokens,  uint256 _available_tokens, uint40 _online_time, address _user_addr) {
    	_total_amount = TOTAL_AMOUNT;
	_withdraw_tokens = withdraw_tokens;
	_available_tokens = this.getAvailableAmount();
	_online_time = online_time;
	_user_addr = user_addr;
    }
}
function getAvailableAmount() view external returns(uint256) {
	uint256 ts = block.timestamp;
	if(ts < online_time)
		return 0;
	uint256 time_span = ts - online_time;
	uint256 index = time_span.div(30*86400);
	uint256 amount = 0;
	for(uint256 i=0; i <= index; i++)
	{
		amount = amount.add(MONTH_TIER[i].mul(10**18));
	}
	if(amount > TOTAL_AMOUNT)
		amount = TOTAL_AMOUNT;
	if(amount < withdraw_tokens)
		amount = 0;
	else
		amount = amount.sub(withdraw_tokens);
	return amount;
    }
/*
 Only external call
 */