contract Loche is CappedToken, BurnableToken
{
    using SafeMath for uint256;

    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    uint256 public transferFee = 100000000;
    uint256 public tokensPerEther = 10000000000;

    mapping( address => bool ) public freezed;

    event Freeze(address indexed acc );
    event Unfreeze(address indexed acc );
    event MintResumed();
    event TokenPurchase( address indexed purchaser, uint256 value, uint256 amount );

    modifier notFreezed() {
        require(!freezed[msg.sender], "This account is freezed!");
        _;
    }

    constructor( uint256 _totalSupply, string _name, uint8 _decimals, string _symbol )
        CappedToken(_totalSupply.mul(2))
        public
    {
        balances[msg.sender] = _totalSupply;              // Give the creator all initial tokens
        totalSupply = _totalSupply;                        // Update total supply
        name = _name;                                   // Set the name for display purposes
        symbol = _symbol;                               // Set the symbol for display purposes
        decimals = _decimals;                            // Amount of decimals for display purposes
    }

    function freeze(address _acc) public onlyOwner
    {
        freezed[_acc] = true;
        emit Freeze(_acc);
    }

    function unfreeze(address _acc) public onlyOwner
    {
        require(freezed[_acc], "Account must be freezed!");
        delete freezed[_acc];
        emit Unfreeze(_acc);
    }

    function setTransferFee(uint256 _value) public onlyOwner
    {
        transferFee = _value;
    }

    function transfer(address _to, uint256 _value) public notFreezed returns (bool)
    {
        return super.transfer(_to, _value);
    }

    /**
   * @dev Owner pay gas and get tranfer fee by XRM.
   * @param _from Address of sender
   * @param _to Address of receiver
   * @param _value Amount of XRM to transfer
   */
    function feedTransfer( address _from, address _to, uint256 _value ) public onlyOwner returns(bool)
    {   // Owner가 가스비를 지불하고, XRM을 전송해주면서 수수료를 XRM으로 받는다.
        require(_value <= balances[msg.sender], "Not enough balance");
        require(_to != address(0), "Receiver address cannot be zero");

        require(!freezed[_from], "Sender account is freezed!");
        require(!freezed[_to], "Receiver account is freezed!");
        require(_value > transferFee, "Value must greater than transaction fee");

        uint256 transferValue = _value.sub(transferFee);
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(transferValue);
        balances[msg.sender] = balances[msg.sender].add(transferFee);

        emit Transfer(_from, _to, transferValue);
        emit Transfer(_from, msg.sender, transferFee);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public returns (bool)
    {
        require(!freezed[_from], "Spender account is freezed!");
        return super.transferFrom(_from, _to, _value);
    }

    function approve(address _spender, uint256 _value) public returns (bool)
    {
        require(!freezed[_spender], "Spender account is freezed!");
        return super.approve(_spender, _value);
    }

    function purchase() public payable
    {
        require(msg.value != 0, "Value must greater than zero");
        uint256 weiAmount = msg.value;
        uint256 tokenAmount = tokensPerEther.mul(weiAmount).div(1 ether);
        balances[msg.sender] = balances[msg.sender].add(tokenAmount);
        totalSupply_ = totalSupply_.add(tokenAmount);

        emit TokenPurchase(msg.sender, msg.value, tokenAmount);
        emit Transfer(address(0), msg.sender, tokenAmount);
    }

    // transfer balance to owner
    function withdrawEther() public onlyOwner
    {
        owner.transfer(address(this).balance);
    }

    // resume stopped minting
    function resumeMint() public onlyOwner returns(bool)
    {
        require(mintingFinished, "Minting is running!");
        mintingFinished = false;
        emit MintResumed();
        return true;
    }
}
/**
 * @title Loche Token
 * @dev Capped, Mitable, Burnable, ERC20 Token
 */
function feedTransfer( address _from, address _to, uint256 _value ) public onlyOwner returns(bool)
{   // Owner가 가스비를 지불하고, XRM을 전송해주면서 수수료를 XRM으로 받는다.
    require(_value <= balances[msg.sender], "Not enough balance");
    require(_to != address(0), "Receiver address cannot be zero");

    require(!freezed[_from], "Sender account is freezed!");
    require(!freezed[_to], "Receiver account is freezed!");
    require(_value > transferFee, "Value must greater than transaction fee");

    uint256 transferValue = _value.sub(transferFee);
    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(transferValue);
    balances[msg.sender] = balances[msg.sender].add(transferFee);

    emit Transfer(_from, _to, transferValue);
    emit Transfer(_from, msg.sender, transferFee);
    return true;
}

/**
 * @dev Owner pay gas and get tranfer fee by XRM.
 * @param _from Address of sender
 * @param _to Address of receiver
 * @param _value Amount of XRM to transfer
 */