package it.playfellas.superapp.logic.master.game23;

import android.util.Log;

import com.squareup.otto.Subscribe;

import org.apache.commons.lang3.ArrayUtils;

import java.util.Arrays;

import it.playfellas.superapp.InternalConfig;
import it.playfellas.superapp.events.EventFactory;
import it.playfellas.superapp.events.game.PopEvent;
import it.playfellas.superapp.events.game.PushEvent;
import it.playfellas.superapp.events.game.StartGameEvent;
import it.playfellas.superapp.logic.Config3;
import it.playfellas.superapp.RandomUtils;
import it.playfellas.superapp.logic.db.TileSelector;
import it.playfellas.superapp.logic.db.query.BinaryOperator;
import it.playfellas.superapp.logic.db.query.Conjunction;
import it.playfellas.superapp.logic.db.query.Shape;
import it.playfellas.superapp.logic.db.query.Type;
import it.playfellas.superapp.tiles.Tile;
import it.playfellas.superapp.tiles.TileColor;
import it.playfellas.superapp.tiles.TileShape;
import it.playfellas.superapp.tiles.TileType;
import it.playfellas.superapp.network.TenBus;

/**
 * Created by affo on 02/09/15.
 */
public class Master3Controller extends Master23Controller {
    private static final String TAG = Master3Controller.class.getSimpleName();
    private Config3 conf;
    private TileSelector ts;
    private Tile[] stack;
    private int stackPtr;

    public Master3Controller(TileSelector ts, Config3 conf) {
        super(conf);
        this.conf = conf;
        this.ts = ts;

        TenBus.get().register(this);
    }

    @Override
    protected Tile[] newBaseTiles() {
        final int size = InternalConfig.NO_FIXED_TILES;
        // remove NONE...
        TileColor[] colors = TileColor.values();
        TileShape[] shapes = TileShape.values();
        int noneIndex;

        noneIndex = ArrayUtils.indexOf(colors, TileColor.NONE);
        colors = ArrayUtils.remove(colors, noneIndex);

        noneIndex = ArrayUtils.indexOf(shapes, TileShape.NONE);
        shapes = ArrayUtils.remove(shapes, noneIndex);

        colors = RandomUtils.choice(colors, size).toArray(new TileColor[size]);
        shapes = RandomUtils.choice(shapes, size).toArray(new TileShape[size]);
        Tile[] tiles = new Tile[InternalConfig.NO_FIXED_TILES];

        for (int i = 0; i < size; i++) {
            tiles[i] = ts.random(1, new Conjunction(
                    new Shape(BinaryOperator.EQUALS, shapes[i]),
//                    new Color(BinaryOperator.EQUALS, colors[i]),
                    new Type(BinaryOperator.EQUALS, TileType.ABSTRACT)
            )).get(0);
        }

        return tiles;
    }

    @Override
    protected synchronized void onBeginStage() {
        super.onBeginStage();
        this.stack = new Tile[InternalConfig.NO_FIXED_TILES];
        Arrays.fill(this.stack, null);
        this.stackPtr = 0;
        nextTurn();
    }

    private void nextTurn() {
        // cloning the stack before posting it
        // because... why not?!?!
        // Seriously, I cannot understand why do
        // I have to do this
        Tile[] cloned = new Tile[stack.length];
        Arrays.fill(cloned, null);
        for (int i = 0; i < cloned.length; i++) {
            if (stack[i] != null) {
                cloned[i] = stack[i].clone();
            }
        }
        TenBus.get().post(EventFactory.yourTurn(nextPlayer(), cloned));
    }

    @Override
    protected void onEndStage() {
        // does nothing
    }

    @Override
    protected StartGameEvent getNewGameEvent() {
        return EventFactory.startGame3(conf);
    }

    @Subscribe
    public synchronized void onPush(PushEvent e) {
        if (stackPtr >= stack.length) {
            Log.d(TAG, "Exceeding stack length!");
        } else {
            stack[stackPtr] = e.getTile();
            stackPtr++;
        }
        nextTurn();
    }

    @Subscribe
    public synchronized void onPop(PopEvent e) {
        if (e.isWrongMove()) {
            // in case someone removed a
            // right tile
            decrementScore();
            notifyScore();
        }

        stackPtr--;
        if (stackPtr < 0) {
            stackPtr = 0;
        }
        stack[stackPtr] = null;

        nextTurn();
    }
}

@@ -113,53 +113,8 @@
 e;%0A%0A
-import org.apache.commons.lang3.ArrayUtils;%0A%0A
 impo
@@ -134,16 +134,16 @@
 Arrays;%0A
+
 %0Aimport 
@@ -181,16 +181,59 @@
 Config;%0A
+import it.playfellas.superapp.RandomUtils;%0A
 import i
@@ -487,51 +487,8 @@
 g3;%0A
-import it.playfellas.superapp.RandomUtils;%0A
 impo
@@ -593,24 +593,76 @@
 ryOperator;%0A
+import it.playfellas.superapp.logic.db.query.Color;%0A
 import it.pl
@@ -806,24 +806,70 @@
 query.Type;%0A
+import it.playfellas.superapp.network.TenBus;%0A
 import it.pl
@@ -1041,54 +1041,8 @@
 ype;
-%0Aimport it.playfellas.superapp.network.TenBus;
 %0A%0A/*
@@ -1614,34 +1614,9 @@
 ES;%0A
-        // remove NONE...
 %0A
+
     
@@ -1663,320 +1663,8 @@
 s();
-%0A        TileShape%5B%5D shapes = TileShape.values();%0A        int noneIndex;%0A%0A        noneIndex = ArrayUtils.indexOf(colors, TileColor.NONE);%0A        colors = ArrayUtils.remove(colors, noneIndex);%0A%0A        noneIndex = ArrayUtils.indexOf(shapes, TileShape.NONE);%0A        shapes = ArrayUtils.remove(shapes, noneIndex);
 %0A%0A  
@@ -1745,88 +1745,8 @@
 %5D);%0A
-        shapes = RandomUtils.choice(shapes, size).toArray(new TileShape%5Bsize%5D);%0A
     
@@ -1900,16 +1900,141 @@
 nction(%0A
+                    // We want shape to be NONE because of db reasons%0A                    // emerged in last specifications.%0A
         
@@ -2082,22 +2082,25 @@
 LS, 
-shapes%5Bi%5D
+TileShape.NONE
 ),%0A
-//
     

Fix in game3 basetiles selection logic