/*
 * Aeronica's mxTune MOD
 * Copyright 2019, Paul Boese a.k.a. Aeronica
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package net.aeronica.mods.mxtune.groups;

import net.aeronica.mods.mxtune.util.ModLogger;

import java.util.function.Supplier;

public class PlayIdSupplier
{

    public enum PlayType implements Supplier<Integer>
    {
        EVENT(500000, 599999) {@Override protected PlayIdSource next(PlayIdSource playIdSource) { return playIdSource;}},
        PERSONAL(40000, 499999) {@Override protected PlayIdSource next(PlayIdSource playIdSource) { return playIdSource;}},
        PLAYERS(300000, 399999) {@Override protected PlayIdSource next(PlayIdSource playIdSource) { return playIdSource;}},
        WORLD(200000, 299999) {@Override protected PlayIdSource next(PlayIdSource playIdSource) { return playIdSource;}},
        AREA(100000, 199999) {@Override protected PlayIdSource next(PlayIdSource playIdSource) { return playIdSource;}},
        ;

        int start;
        int end;
        PlayIdSource playIdSource;
        PlayType playType;

        private static final PlayIdSource INVALID_ID = new PlayIdSource(-1, -1);
        public static final int INVALID = -1;

        PlayType(int start, int end)
        {
            this.start = start;
            this.end = end;
            playIdSource = new PlayIdSource(start, end);
            this.playType = this;
        }

        protected PlayIdSource next(PlayIdSource playIdSource) { return INVALID_ID; }

        @Override
        public Integer get()
        {
            int id = playIdSource.get();
            ModLogger.debug("Type: %s, start: %d, end: %s, id: %d", playType, start, end, id);
            return id;
        }

    }

    private static class PlayIdSource implements Supplier<Integer>
    {
        int start;
        int end;
        int range;
        int counter;

        PlayIdSource(int startIn, int endIn)
        {
            start =  Math.min(startIn, endIn);
            end =  Math.max(startIn, endIn) + 1;
            // range = end + 1 - start
            range = Math.abs(end - start);
        }

        // bounded inclusive integer from start to end that rolls over
        @Override
        public Integer get()
        {
            return (counter++ % range) + start;
        }
    }
}

@@ -738,16 +738,79 @@
 ogger;%0A%0A
+import javax.annotation.Nullable;%0Aimport java.util.Comparator;%0A
 import j
@@ -868,17 +868,16 @@
 plier%0A%7B%0A
-%0A
     publ
@@ -913,32 +913,54 @@
 upplier%3CInteger%3E
+, Comparator%3CPlayType%3E
 %0A    %7B%0A        E
@@ -1094,16 +1094,17 @@
 AL(40000
+0
 , 499999
@@ -2003,32 +2003,333 @@
 his;%0A        %7D%0A%0A
+        @Nullable%0A        public PlayType getTypeForPlayId(int playId)%0A        %7B%0A            for (PlayType playType : values())%0A            %7B%0A                if (playId %3E= playType.start && playId %3C= playType.end)%0A                    return playType;%0A            %7D%0A            return null;%0A        %7D%0A%0A
         protecte
@@ -2622,24 +2622,417 @@
 %0A        %7D%0A%0A
+        @Nullable%0A        Integer compare(int playId1, int playId2)%0A        %7B%0A            PlayType p1 = getTypeForPlayId(playId1);%0A            PlayType p2 = getTypeForPlayId(playId2);%0A            return p1 != null && p2 != null ? compare(p1, p2) : null;%0A        %7D%0A%0A        @Override%0A        public int compare(PlayType o1, PlayType o2)%0A        %7B%0A            return o2.compareTo(o1);%0A        %7D%0A
     %7D%0A%0A    p
@@ -3611,11 +3611,299 @@
  %7D%0A    %7D
+%0A%0A    @Nullable%0A    public static Integer compare(int playId1, int playId2)%0A    %7B%0A        return PlayType.EVENT.compare(playId1, playId2);%0A    %7D%0A%0A    public static int compare(PlayType playType1, PlayType playType2)%0A    %7B%0A        return PlayType.EVENT.compare(playType1, playType2);%0A    %7D
 %0A%7D%0A

Add compare methods for priority management.