/*
 *
 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package java2d;


/**
 * Demos that animate extend this class.
 */
@SuppressWarnings("serial")
public abstract class AnimatingSurface extends Surface implements Runnable {

    private volatile boolean running = false;

    private volatile Thread thread;

    public abstract void step(int w, int h);

    public abstract void reset(int newwidth, int newheight);


    public synchronized void start() {
        if (!running() && !dontThread) {
            thread = new Thread(this);
            thread.setPriority(Thread.MIN_PRIORITY);
            thread.setName(name + " Demo");
            thread.start();
            running = true;
        }
    }


    public synchronized void stop() {
        if (thread != null) {
            running = false;
            thread.interrupt();
        }
        thread = null;
        notifyAll();
    }


    @Override
    @SuppressWarnings("SleepWhileHoldingLock")
    public void run() {

        while (running() && !isShowing() || getSize().width == 0) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException ignored) {
            }
        }

        while (running()) {
            repaint();
            try {
                Thread.sleep(sleepAmount);
            } catch (InterruptedException ignored) {
            }
        }
        synchronized (this) {
            running = false;
        }
    }

    /**
     * @return the running
     */
    public synchronized boolean running() {
        return running;
    }

    /**
     * Causes surface to repaint immediately
     */
    public synchronized void doRepaint() {
        if (running() && thread != null) {
            thread.interrupt();
        }
    }
}
