contract ALXERC20 is Ownable {

    using SafeMath for uint256;


    mapping (address => uint256) public balances;

    mapping (address => mapping (address => uint256)) internal allowed;

    mapping (address => mapping (uint256 => timeHold)) internal requestWithdraws;
   
 

    struct timeHold{
        uint256[] amount;
        uint256[] time;
        uint256 length;
    }
   
   function requestOfAmount(address addr, uint256 n) public view returns(uint256){
     return requestWithdraws[addr][n].amount[0];   
    }   
   
    function requestOfTime(address addr, uint256 n) public view returns(uint256){
     return requestWithdraws[addr][n].time[0];   
    }  
    
    uint256 public roundCounter=0;
    
    /* Public variables for the ERC20 token */
    string public constant standard = "ERC20 ALX";
    uint8 public constant decimals = 8; // hardcoded to be a constant
    uint256 public totalSupply;
    string public name;
    string public symbol;

    uint256 public transactionFee = 1;

    uint256 public icoEnd=0;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);


    function balanceOf(address _owner) public view returns (uint256 balance) {
        return balances[_owner];
    }


    function setTransactionFee(uint256 _value) public onlyOwner{
      transactionFee=_value;
 
    }

    function setIcoEnd(uint256 _value) public onlyOwner{
      icoEnd=_value;
 
    }

    function transfer(address _to, uint256 _value) public returns (bool) {

        require(_to != address(0));
        require(_value <= balances[msg.sender]);
        require(block.timestamp>icoEnd);
        // SafeMath.sub will throw if there is not enough balance.
        balances[msg.sender] = balances[msg.sender].sub(_value);

        uint256 fee=(_value*transactionFee)/1000;
 
        delete requestWithdraws[msg.sender][roundCounter];

        balances[_to] = balances[_to].add(_value-fee);
        balances[owner]=balances[owner].add(fee);
        
        emit Transfer(msg.sender, _to, _value-fee);
        emit Transfer(msg.sender, owner, fee);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
        require(_value <= balances[_from]);
        require(_value <= allowed[_from][msg.sender]);
        require(block.timestamp>icoEnd);
        balances[_from] = balances[_from].sub(_value);

        uint256 fee=(_value*transactionFee)/1000;

        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);

        delete requestWithdraws[msg.sender][roundCounter];
        delete requestWithdraws[_from][roundCounter];

        balances[_to] = balances[_to].add(_value-fee);
        balances[owner]=balances[owner].add(fee);
        
        emit Transfer(_from, _to, _value-fee);
        emit Transfer(_from, owner, fee);
        return true;
    }

    function approve(address _spender, uint256 _value) public returns (bool) {
        allowed[msg.sender][_spender] = _value;
        emit Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) public view returns (uint256) {
        return allowed[_owner][_spender];
    }

    function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

    function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
        uint oldValue = allowed[msg.sender][_spender];
        if (_subtractedValue > oldValue) {
            allowed[msg.sender][_spender] = 0;
        } else {
            allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
        }
        emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
    }

    /* Approve and then communicate the approved contract in a single tx */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
        tokenRecipient spender = tokenRecipient(_spender);

        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }
}
//////////////////////////////////////////////////////////////
function approveAndCall(address _spender, uint256 _value, bytes _extraData) public returns (bool success) {
    tokenRecipient spender = tokenRecipient(_spender);

    if (approve(_spender, _value)) {
        spender.receiveApproval(msg.sender, _value, this, _extraData);
        return true;
    }
}

/* Approve and then communicate the approved contract in a single tx */