contract AJAToken is ERC20,ERC20Detailed,Ownable,ERC20Burnable{

    using SafeMath for uint256;

    mapping(address => uint256) internal _lockedHolder;


    string internal constant INVALID_TOKEN_VALUES = 'Invalid token values';
	string internal constant NOT_ENOUGH_TOKENS = 'Not enough tokens';
	string internal constant ALREADY_LOCKED = 'Tokens already locked';
	string internal constant NOT_LOCKED = 'No tokens locked';
	string internal constant AMOUNT_ZERO = 'Amount can not be 0';
    string internal constant LOCKED_ADDRESS = 'Locked';
    string internal constant OPERATION_NOT_PERMITTED = 'Operation not permitted';

//    bool public isLock = true;

    constructor(string memory name, string memory symbol, uint8 decimals, uint256 totalSupply)
	ERC20Detailed(name, symbol, decimals)
	public {
		_mint(owner(), totalSupply * 10**uint(decimals));
	}
/*
    function unLock() public onlyOwner{
        isLock = false;
    }

    function lock() public onlyOwner{
        isLock = true;
    }

    function isLocked() public view returns (bool){
        return isLock;
    }
*/
    modifier OwnerOrReleased(){

        if(owner() != msg.sender)
        {
            if(hasLocked(msg.sender))
            {
                require(lockUntil(msg.sender) < now,LOCKED_ADDRESS);
            }
        }
        _;
    }

    function lock(address _of,uint256 _time) public onlyOwner
    {
        // per second 
        uint256 validUntil = now.add(_time);
        _lockedHolder[_of] = validUntil;
    }

    function hasLocked(address _of) public view returns (bool)
    {
        return (_lockedHolder[_of] > 0);
    }

    function isLock(address _of) public view returns (bool)
    {
        return !(lockUntil(_of) < now);   
    }

    function lockUntil(address _of) public view returns (uint256)
    {
        return _lockedHolder[_of];
    }

    function transfer(address to,uint256 value) public OwnerOrReleased returns (bool) {

        return super.transfer(to,value);
    }

    function allowance(address owner,address spender) public OwnerOrReleased view returns (uint256) {
        return super.allowance(owner,spender);
    }

    function increaseAllowance(address spender, uint addedValue) public OwnerOrReleased returns (bool) {
        return super.increaseAllowance(spender, addedValue);
    }

    function decreaseAllowance(address spender, uint subtractedValue) public OwnerOrReleased returns (bool) {
        return super.decreaseAllowance(spender, subtractedValue);
    }

    function transferFrom(address from,address to,uint256 value) public OwnerOrReleased returns (bool){
        return super.transferFrom(from,to,value);
    }

    function approve(address spender,uint256 value) public OwnerOrReleased returns (bool){
        return super.approve(spender,value);
    }

    function burn(uint256 amount) public onlyOwner{
        super.burn(amount);
    }

    /**
     * @dev See `ERC20._burnFrom`.
     */
    function burnFrom(address account, uint256 amount) public onlyOwner {
        super.burnFrom(account,amount);
    }

/*
    event Burn(address indexed burner,uint256 _value);

    function burn(uint256 _value) public onlyOwner {
        require(_value > 0 ,INVALID_TOKEN_VALUES);

        address burner = msg.sender;
        require(_value <= balances[burner], NOT_ENOUGH_TOKENS);
        
        balances[burner] = balances[burner].sub(_value);
        totalSupply = totalSupply.sub(_value);
        emit Burn(msg.sender, _value);
    }

    function burnFrom(address burner,uint256 _value) public onlyOwner
    {
        require(_value > 0 ,INVALID_TOKEN_VALUES);
        require(_value <= balances[burner], NOT_ENOUGH_TOKENS);

        balances[burner] = balances[burner].sub(_value);
        totalSupply = totalSupply.sub(_value);
        emit Burn(burner, _value);
    }
    */
}
function burnFrom(address account, uint256 amount) public onlyOwner {
    super.burnFrom(account,amount);
}

/**
 * @dev See `ERC20._burnFrom`.
 */