package de.duehl.swing.ui.highlightingeditor.multiplereactor;

/*
 * Copyright 2017 Christian Dühl. All rights reserved.
 *
 * This program is free software. You can redistribute it and/or
 * modify it under the same terms as perl:
 *
 * general:  http://dev.perl.org/licenses/
 * GPL:      http://dev.perl.org/licenses/gpl1.html
 * artistic: http://dev.perl.org/licenses/artistic.html
 */

import java.util.ArrayList;
import java.util.List;

/**
 * Diese Klasse können verschiedene Seiten sagen, ob Reaktionen stattfinden sollen oder nicht.
 *
 * Wenn die erste Seite sagt, dass Reaktionen nicht stattfinden werden, so werden diese
 * unterbrochen.
 *
 * Wenn die letzte Seite sagt, dass die Reaktionen wieder erfolgen dürfen, so werden diese
 * wieder aktiv geschaltet.
 *
 * @version 1.01     2017-11-21
 * @author Christian Dühl
 */

public class MultipleChangeReactor implements ChangeReactor {

    private static final boolean DEBUG = false;

    /** Zähler, wird bei jedem doNotRect erhöht und bei jedem doRecact verringert. */
    private int counter;

    /** Liste der Objekte, die bei Änderungen informiert werden sollen. */
    private final List<ChangeReactor> reactors;

    /** Konstruktor. */
    public MultipleChangeReactor() {
        counter = 0;
        reactors = new ArrayList<>();
    }

    /** Fügt ein Objekt hinzu, das bei Änderungen informiert werden soll. */
    public void addChangeReactor(ChangeReactor reactor) {
        reactors.add(reactor);
    }

    /** Gibt an, dass momentan Änderungen durchgeführt werden sollen. */
    @Override
    synchronized
    public void reactOnChanges() {
        say("MultipleChangeReactor - reactOnChanges() - counter = " + counter);

        if (counter == 0) {
            throw new RuntimeException("reactOnChanges() vor doNotReactOnChanges() aufgerufen!");
        }

        --counter;
        say("    nun: counter = " + counter);

        if (0 == counter) {
            say("    Sage allen ChangeReactors, dass sie nun wieder reagieren sollen.");
            for (ChangeReactor reactor : reactors) {
                reactor.reactOnChanges();
            }
        }
    }

    /** Gibt an, dass momentan keine Änderungen durchgeführt werden sollen. */
    @Override
    synchronized
    public void doNotReactOnChanges() {
        say("MultipleChangeReactor - doNotReactOnChanges() - counter = " + counter);

        if (0 == counter) {
            say("    Sage allen ChangeReactors, dass sie nicht mehr reagieren sollen.");
            for (ChangeReactor reactor : reactors) {
                reactor.doNotReactOnChanges();
            }
        }

        ++counter;
        say("    nun counter = " + counter);
    }

    private void say(String message) {
        if (DEBUG) {
            System.out.println(message);
        }
    }

}
