contract StrikeToken is MintableToken, Pausable, BlockableToken{
    string public name = "Dimensions Strike Token";
    string public symbol = "DST";
    uint256 public decimals = 18;

    event Ev(string message, address whom, uint256 val);

    struct XRec {
        bool inList;
        address next;
        address prev;
        uint256 val;
    }

    struct QueueRecord {
        address whom;
        uint256 val;
    }

    address first = 0x0;
    address last = 0x0;

    mapping (address => XRec) public theList;

    QueueRecord[]  theQueue;

    // add a record to the END of the list
    function add(address whom, uint256 value) internal {
        theList[whom] = XRec(true,0x0,last,value);
        if (last != 0x0) {
            theList[last].next = whom;
        } else {
            first = whom;
        }
        last = whom;
        emit Ev("add",whom,value);
    }

    function remove(address whom) internal {
        if (first == whom) {
            first = theList[whom].next;
            theList[whom] = XRec(false,0x0,0x0,0);
            return;
        }
        address next = theList[whom].next;
        address prev = theList[whom].prev;
        if (prev != 0x0) {
            theList[prev].next = next;
        }
        if (next != 0x0) {
            theList[next].prev = prev;
        }
        theList[whom] =XRec(false,0x0,0x0,0);
        emit Ev("remove",whom,0);
    }

    function update(address whom, uint256 value) internal {
        if (value != 0) {
            if (!theList[whom].inList) {
                add(whom,value);
            } else {
                theList[whom].val = value;
                emit Ev("update",whom,value);
            }
            return;
        }
        if (theList[whom].inList) {
            remove(whom);
        }
    }

    /**
     * @dev Allows anyone to transfer the Strike tokens once trading has started
     * @param _to the recipient address of the tokens.
     * @param _value number of tokens to be transfered.
     */
    function transfer(address _to, uint _value) public whenNotPaused whenNotBlocked returns (bool) {
        bool result = super.transfer(_to, _value);
        update(msg.sender,balances[msg.sender]);
        update(_to,balances[_to]);
        return result;
    }

    /**
     * @dev Allows anyone to transfer the Strike tokens once trading has started
     * @param _from address The address which you want to send tokens from
     * @param _to address The address which you want to transfer to
     * @param _value uint the amout of tokens to be transfered
     */
    function transferFrom(address _from, address _to, uint _value) public whenNotPaused whenNotBlocked returns (bool) {
        bool result = super.transferFrom(_from, _to, _value);
        update(_from,balances[_from]);
        update(_to,balances[_to]);
        return result;
    }

    /**
     * @dev Function to mint tokens
     * @param _to The address that will recieve the minted tokens.
     * @param _amount The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */

    function mint(address _to, uint256 _amount) public onlyOwner canMint returns (bool) {
        bool result = super.mint(_to,_amount);
        update(_to,balances[_to]);
        return result;
    }

    constructor()  public{
        owner = msg.sender;
    }

    function changeOwner(address newOwner) public onlyOwner {
        owner = newOwner;
    }
}
function add(address whom, uint256 value) internal {
        theList[whom] = XRec(true,0x0,last,value);
        if (last != 0x0) {
            theList[last].next = whom;
        } else {
            first = whom;
        }
        last = whom;
        emit Ev("add",whom,value);
    }
// add a record to the END of the list