contract TransferFee is Ownable, ITST {

    address private _feeAccount;
    uint256 private _maxTransferFee;
    uint256 private _minTransferFee;
    uint256 private _transferFeePercentage;
    
    /**
     * @dev Constructor, _feeAccount that collects tranfer fee, fee percentange, maximum, minimum amount of wei for trasfer fee.
     * @param feeAccount account that collects fee.
     * @param minTransferFee Min amount of wei to be charged on trasfer.
     * @param minTransferFee Min amount of wei to be charged on trasfer.
     * @param transferFeePercentage Percent amount of wei to be charged on trasfer.
     */
    constructor (address feeAccount, uint256 maxTransferFee, uint256 minTransferFee, uint256 transferFeePercentage) public {
        require(feeAccount != address(0x0), "TransferFee: feeAccount is 0");
        require(minTransferFee > 0, "TransferFee: minTransferFee is 0");
        require(maxTransferFee > 0, "TransferFee: maxTransferFee is 0");
        require(transferFeePercentage > 0, "TransferFee: transferFeePercentage is 0");
        
        // this also handles "minTransferFee should be less than maxTransferFee"
        // solhint-disable-next-line max-line-length
        require(maxTransferFee > minTransferFee, "TransferFee: maxTransferFee should be greater than minTransferFee");

        _feeAccount = feeAccount;
        _maxTransferFee = maxTransferFee;
        _minTransferFee = minTransferFee;
        _transferFeePercentage = transferFeePercentage;
    }
    
    /**
     * See {ITrasnferFee-setFeeAccount}.
     * 
     * @dev sets `feeAccount` to `_feeAccount` by the caller.
     *
     * Requirements:
     *
     * - `feeAccount` cannot be the zero.
     */
    function setFeeAccount(address feeAccount) external onlyOwner returns (bool) {
        require(feeAccount != address(0x0), "TransferFee: feeAccount is 0");
        
        emit FeeAccountUpdated(_feeAccount, feeAccount);
        _feeAccount = feeAccount;
        return true;
    }
    
    /**
     * See {ITrasnferFee-setMaxTransferFee}.
     * 
     * @dev sets `maxTransferFee` to `_maxTransferFee` by the caller.
     * 
     * Requirements:
     *
     * - `maxTransferFee` cannot be the zero.
     * - `maxTransferFee` should be greater than minTransferFee.
     */
    function setMaxTransferFee(uint256 maxTransferFee) external onlyOwner returns (bool) {
        require(maxTransferFee > 0, "TransferFee: maxTransferFee is 0");
        // solhint-disable-next-line max-line-length
        require(maxTransferFee > _minTransferFee, "TransferFee: maxTransferFee should be greater than minTransferFee");
        
        emit MaxTransferFeeUpdated(_maxTransferFee, maxTransferFee);
        _maxTransferFee = maxTransferFee;
        return true;
    }

    /**
     * See {ITrasnferFee-setMinTransferFee}.
     * 
     * @dev sets `minTransferFee` to `_minTransferFee` by the caller.
     *
     * Requirements:
     *
     * - `minTransferFee` cannot be the zero.
     * - `minTransferFee` should be less than maxTransferFee.
     */
    function setMinTransferFee(uint256 minTransferFee) external onlyOwner returns (bool) {
        require(minTransferFee > 0, "TransferFee: minTransferFee is 0");
        // solhint-disable-next-line max-line-length
        require(minTransferFee < _maxTransferFee, "TransferFee: minTransferFee should be less than maxTransferFee");
        
        emit MaxTransferFeeUpdated(_minTransferFee, minTransferFee);
        _minTransferFee = minTransferFee;
        return true;
    }

    /**
     * See {ITrasnferFee-setTransferFeePercentage}.
     * 
     * @dev sets `transferFeePercentage` to `_transferFeePercentage` by the caller.
     *
     * Requirements:
     *
     * - `transferFeePercentage` cannot be the zero.
     * - `transferFeePercentage` should be less than maxTransferFee.
     */
    function setTransferFeePercentage(uint256 transferFeePercentage) external onlyOwner returns (bool) {
        require(transferFeePercentage > 0, "TransferFee: transferFeePercentage is 0");
        
        emit TransferFeePercentageUpdated(_transferFeePercentage, transferFeePercentage);
        _transferFeePercentage = transferFeePercentage;
        return true;
    }
    
    /**
     * @dev See {ITrasnferFee-feeAccount}.
     */    
    function feeAccount() public view returns (address) {
        return _feeAccount;
    }

    /**
     * See {ITrasnferFee-maxTransferFee}.
     */
    function maxTransferFee() public view returns (uint256) {
        return _maxTransferFee;
    }
    
    /**
     * See {ITrasnferFee-minTransferFee}.
     */
    function minTransferFee() public view returns (uint256) {
        return _minTransferFee;
    }

    /**
     * See {ITrasnferFee-transferFeePercentage}.
     */ 
    function transferFeePercentage() public view returns (uint256) {
        return _transferFeePercentage;
    }
}
/*
 * TransferFee 
 * Base contract for trasfer fee specification.
 */
function setMaxTransferFee(uint256 maxTransferFee) external onlyOwner returns (bool) {
    require(maxTransferFee > 0, "TransferFee: maxTransferFee is 0");
    // solhint-disable-next-line max-line-length
    require(maxTransferFee > _minTransferFee, "TransferFee: maxTransferFee should be greater than minTransferFee");
        
    emit MaxTransferFeeUpdated(_maxTransferFee, maxTransferFee);
    _maxTransferFee = maxTransferFee;
    return true;
}

/**
 * See {ITrasnferFee-setMaxTransferFee}.
 * 
 * @dev sets `maxTransferFee` to `_maxTransferFee` by the caller.
 * 
 * Requirements:
 *
 * - `maxTransferFee` cannot be the zero.
 * - `maxTransferFee` should be greater than minTransferFee.
 */