package com.inari.firefly.system.external;

import java.util.HashMap;
import java.util.Map;

import com.inari.commons.lang.list.DynArray;

public abstract class FFTimer {
    
    protected long lastUpdateTime, time, timeElapsed;
    
    private final Map<Float, UpdateScheduler> updateSchedulers;
    private final DynArray<UpdateScheduler> schedulers;
    
    protected FFTimer() {
        lastUpdateTime = 0;
        time = 0;
        timeElapsed = 0;
        updateSchedulers = new HashMap<Float, UpdateScheduler>();
        schedulers = DynArray.create( UpdateScheduler.class, 20 );
    }

    public final long getLastUpdateTime() {
        return lastUpdateTime;
    }

    public final long getTime() {
        return time;
    }

    public final long getTimeElapsed() {
        return timeElapsed;
    }
    
    public final void updateSchedulers() {
        for ( int i = 0; i < schedulers.capacity(); i++ ) {
            UpdateScheduler updateScheduler = schedulers.get( i );
            if ( updateScheduler == null ) {
                continue;
            } 
            
            updateScheduler.update();
        }
    }

    public abstract void tick();
    
    public final UpdateScheduler createUpdateScheduler( float resolution ) {
        UpdateScheduler updateScheduler = updateSchedulers.get( resolution );
        if ( updateScheduler == null ) {
            updateScheduler = new UpdateScheduler( resolution );
            updateSchedulers.put( resolution, updateScheduler );
            schedulers.add( updateScheduler );
        }
        
        return updateScheduler;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "FFTimer [lastUpdateTime=" );
        builder.append( lastUpdateTime );
        builder.append( ", time=" );
        builder.append( time );
        builder.append( ", timeElapsed=" );
        builder.append( timeElapsed );
        builder.append( "]" );
        return builder.toString();
    }

    public final class UpdateScheduler {
        
        private final float resolution;
        private final long delayMillis;
        private long lastUpdate = -1;
        private long tick = 0;
        private boolean needsUpdate;
        
        private UpdateScheduler( float resolution ) {
            this.resolution = resolution;
            delayMillis = (long) ( 1000 / resolution );
        }
        
        public final float getResolution() {
            return resolution;
        }

        public final long getTick() {
            return tick;
        }
        
        final void update() {
            if ( lastUpdateTime - lastUpdate >= delayMillis ) {
                lastUpdate = lastUpdateTime;
                tick++;
                needsUpdate = true;
            } else if ( needsUpdate ) {
                needsUpdate = false;
            }
        }

        public final boolean needsUpdate() {
            return needsUpdate;
        }
        
        public final void reset() {
            lastUpdate = -1;
            tick = 0;
        }

    }

}

@@ -2254,32 +2254,65 @@
 an needsUpdate;%0A
+        private boolean updated;%0A
         %0A       
@@ -2867,27 +2867,23 @@
 se if ( 
-needsU
+u
 pdate
+d
  ) %7B%0A   
@@ -2916,16 +2916,49 @@
  false;%0A
+                updated = false;%0A
         
@@ -3011,32 +3011,111 @@
 needsUpdate() %7B%0A
+            if ( needsUpdate ) %7B%0A                updated = true;%0A            %7D%0A
             retu

fix timer scheduler with updated flag