/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 27-Oct-2004
 */
package uk.ac.ic.doc.kevlar.gui.internal.animation;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import uk.ac.ic.doc.kevlar.gui.internal.CanvasManager;

/**
 * @author Marc
 */
public class AnimationManager {

    private static AnimationManager singleton;

    protected List<AAnimation> animations;

    protected Timer timer;

    protected ArrayList<AAnimationListenerEntry> listenerGroups;

    public class TickTimerTask extends TimerTask {

        public void run() {

            synchronized(animations) {
            
                int i = 0;
                
                while (i < animations.size()) {
                    
                    if (!animations.get(i).animate(
                            System.currentTimeMillis())) {
                        
                        AAnimation animation = animations.get(i);
                        
                        animation.animationEnd();
                        animations.remove(i);
                        
                        int j = 0;
                        
                        while (j < listenerGroups.size()) {
                            
                            AAnimationListenerEntry e = listenerGroups
                            .get(j);
                            
                            if (e instanceof AnimationGroupListenerEntry) {
                                
                                AnimationGroupListenerEntry entry = (AnimationGroupListenerEntry) e;
                                entry.animations.remove(animation);
                                
                                if (entry.animations.isEmpty()) {
                                    
                                    entry.listener.animationFinished();
                                    listenerGroups.remove(j);
                                    
                                } else {
                                    
                                    j++;
                                    
                                }
                                
                            } else if (e instanceof AnimationListenerEntry) {
                                
                                AnimationListenerEntry entry = (AnimationListenerEntry) e;
                                
                                if (entry.animation == animation) {
                                    
                                    entry.listener.animationFinished();
                                    listenerGroups.remove(j);
                                    
                                } else {
                                    
                                    j++;
                                    
                                }
                                
                            } else {
                                
                                listenerGroups.remove(j);
                                
                            }
                            
                        }
                        
                    } else {
                        
                        i++;
                        
                    }
                    
                }
                
                if( i > 0 ) {
                    
                    CanvasManager.getSingleton().applyRedraw();
                    
                }
                
            }
            
        }

    }

    private AnimationManager() {

        animations = new ArrayList<AAnimation>();
        listenerGroups = new ArrayList<AAnimationListenerEntry>();
        timer = new Timer("Animation Thread", true);
        timer.schedule(new TickTimerTask(), 0, 10);
        // timer.schedule(new TickTimerTask(), 10);

    }

    public static void createSingleton() {

        singleton = new AnimationManager();

    }

    public static AnimationManager getSingleton() {

        return singleton;

    }

    public void addAnimation(AAnimation animation) {

        synchronized(animations) {
        
            for (int i = 0; i < animations.size(); i++) {
                
                if (animations.get(i).getTarget() == animation.getTarget()) {

                    animations.remove(i);

                }

            }

            animations.add(animation);
            animation.animationStart();
            
        }

    }

    public void removeAnimation(AAnimation animation) {

        synchronized(animations) {
        
            animations.remove(animation);
            
        }

    }

    public void addAnimationListener(AAnimationListenerEntry entry) {

        listenerGroups.add(entry);

    }

    public void dispose() {

        timer.cancel();

    }

}
