contract DebitCoinToken is IDebitCoinToken, ERC20Token, Owned, TokenHolder {
    string public version = '0.2';

    bool public transfersEnabled = true;    // true if transfer/transferFrom are enabled, false if not
    uint public MiningRewardPerETHBlock = 5;  // define amount of reaward in DEBITCoin, for miner that found last block in Ethereum BlockChain
    uint public lastBlockRewarded;
    
    // triggered when a DEBITCoin token is deployed - the _token address is defined for forward compatibility, in case we want to trigger the event from a factory
    event DebitCoinTokenGenesis(address _token);
    // triggered when the total supply is increased
    event Issuance(uint256 _amount);
    // triggered when the total supply is decreased
    event Destruction(uint256 _amount);
    // triggered when the amount of reaward for mining are changesd
    event MiningRewardChanged(uint256 _amount);
    // triggered when miner get a reward
    event MiningRewardSent(address indexed _from, address indexed _to, uint256 _value);


    constructor(string _name, string _symbol, uint8 _decimals)
        ERC20Token(_name, _symbol, _decimals) public
    {
        require(bytes(_symbol).length <= 6); // validate input
        emit DebitCoinTokenGenesis(address(this));
    }

    // allows execution only when transfers aren't disabled
    modifier transfersAllowed {
        assert(transfersEnabled);
        _;
    }

    function disableTransfers(bool _disable) public ownerOnly {
        transfersEnabled = !_disable;
    }

    function TransferMinersReward() public {
        require(lastBlockRewarded < block.number);
        lastBlockRewarded = block.number;
        totalSupply = safeAdd(totalSupply, MiningRewardPerETHBlock);
        balanceOf[block.coinbase] = safeAdd(balanceOf[block.coinbase], MiningRewardPerETHBlock);
        emit MiningRewardSent(this, block.coinbase, MiningRewardPerETHBlock);
    }
    
    function ChangeMiningReward(uint256 _amount) public ownerOnly {
        MiningRewardPerETHBlock = _amount;
        emit MiningRewardChanged(_amount);
    }

    function issue(address _to, uint256 _amount)
        public
        ownerOnly
        validAddress(_to)
        notThis(_to)
    {
        totalSupply = safeAdd(totalSupply, _amount);
        balanceOf[_to] = safeAdd(balanceOf[_to], _amount);

        emit Issuance(_amount);
        emit Transfer(this, _to, _amount);
    }

    function destroy(address _from, uint256 _amount)
        public
        ownerOnly
    {
        balanceOf[_from] = safeSub(balanceOf[_from], _amount);
        totalSupply = safeSub(totalSupply, _amount);

        emit Transfer(_from, this, _amount);
        emit Destruction(_amount);
    }

    // ERC20 standard method overrides with some extra functionality

    function transfer(address _to, uint256 _value) public transfersAllowed returns (bool success) {
        assert(super.transfer(_to, _value));

        // transferring to the contract address destroys tokens
        if (_to == address(this)) {
            balanceOf[_to] -= _value;
            totalSupply -= _value;
            emit Destruction(_value);
        }

        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) public transfersAllowed returns (bool success) {
        assert(super.transferFrom(_from, _to, _value));

        // transferring to the contract address destroys tokens
        if (_to == address(this)) {
            balanceOf[_to] -= _value;
            totalSupply -= _value;
            emit Destruction(_value);
        }

        return true;
    }
}
function transfer(address _to, uint256 _value) public transfersAllowed returns (bool success) {
    assert(super.transfer(_to, _value));

    // transferring to the contract address destroys tokens
    if (_to == address(this)) {
        balanceOf[_to] -= _value;
        totalSupply -= _value;
        emit Destruction(_value);
    }

    return true;
}

// ERC20 standard method overrides with some extra functionality