package com.github.apixandru.games.rummikub.server;

import com.github.apixandru.games.rummikub.brotocol.IntReader;
import com.github.apixandru.games.rummikub.brotocol.IntWriter;
import com.github.apixandru.games.rummikub.brotocol.util.AbstractIntWritable;
import com.github.apixandru.games.rummikub.model.Card;
import com.github.apixandru.games.rummikub.model.Player;
import com.github.apixandru.games.rummikub.model.PlayerCallback;

import java.io.IOException;
import java.util.List;

import static com.github.apixandru.games.rummikub.brotocol.Brotocol.SERVER_CARD_PLACED;
import static com.github.apixandru.games.rummikub.brotocol.Brotocol.SERVER_CARD_REMOVED;
import static com.github.apixandru.games.rummikub.brotocol.Brotocol.SERVER_RECEIVED_CARD;

/**
 * @author Alexandru-Constantin Bledea
 * @since January 04, 2016
 */
public class ClientRunnable extends AbstractIntWritable implements Runnable, PlayerCallback<Integer>, Player<Integer> {

    private final IntReader intReader;

    /**
     * @param reader
     * @param writer
     * @param cards
     * @throws IOException
     */
    ClientRunnable(final IntReader reader, final IntWriter writer, final List<Card> cards) throws IOException {
        super(writer, cards);
        this.intReader = reader;
    }

    @Override
    public void run() {
        try (IntReader reader = intReader) {
            while (true) {
                final int input = reader.readInt();
                System.out.println(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void cardReceived(final Card card, final Integer hint) {
        write(SERVER_RECEIVED_CARD, card, hint == null ? -1 : hint);
    }

    @Override
    public void onCardPlacedOnBoard(final Card card, final int x, final int y) {
        write(SERVER_CARD_PLACED, card, x, y);
    }

    @Override
    public void onCardRemovedFromBoard(final Card card, final int x, final int y) {
        write(SERVER_CARD_REMOVED, card, x, y);
    }

    @Override
    public void placeCardOnBoard(final Card card, final int x, final int y) {

    }

    @Override
    public void moveCardOnBoard(final Card card, final int fromX, final int fromY, final int toX, final int toY) {

    }

    @Override
    public void takeCardFromBoard(final Card card, final int x, final int y, final Integer hint) {

    }

    @Override
    public void endTurn() {

    }

    @Override
    public boolean canMoveCardOffBoard(final Card card) {
        return false;
    }
}

@@ -431,60 +431,461 @@
 ck;%0A
-%0Aimport java.io.IOException;%0Aimport java.util.List;%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.io.IOException;%0Aimport java.util.List;%0A%0Aimport static com.github.apixandru.games.rummikub.brotocol.Brotocol.CLIENT_END_TURN;%0Aimport static com.github.apixandru.games.rummikub.brotocol.Brotocol.CLIENT_MOVE_CARD;%0Aimport static com.github.apixandru.games.rummikub.brotocol.Brotocol.CLIENT_PLACE_CARD;%0Aimport static com.github.apixandru.games.rummikub.brotocol.Brotocol.CLIENT_TAKE_CARD;
 %0Aimp
@@ -1340,24 +1340,110 @@
 Integer%3E %7B%0A%0A
+    private static final Logger log = LoggerFactory.getLogger(ClientRunnable.class);%0A%0A
     private 
@@ -1939,125 +1939,1474 @@
     
-System.out.println(input);%0A            %7D%0A        %7D catch (IOException e) %7B%0A            e.printStackTrace();%0A        %7D
+switch (input) %7B%0A                    case CLIENT_PLACE_CARD:%0A                        handleOnCardPlacedOnBoard(reader);%0A                        break;%0A                    case CLIENT_END_TURN:%0A                        endTurn();%0A                        break;%0A                    case CLIENT_TAKE_CARD:%0A                        takeCardFromBoard(readCard(reader), reader.readInt(), reader.readInt(), reader.readInt());%0A                        break;%0A                    case CLIENT_MOVE_CARD:%0A                        moveCardOnBoard(readCard(reader), reader.readInt(), reader.readInt(), reader.readInt(), reader.readInt());%0A                        break;%0A                    default:%0A                        throw new IllegalArgumentException(%22Unknown input: %22 + input);%0A                %7D%0A            %7D%0A        %7D catch (IOException e) %7B%0A            e.printStackTrace();%0A        %7D%0A    %7D%0A%0A    private void handleOnCardPlacedOnBoard(final IntReader reader) throws IOException %7B%0A        log.info(%22Received on onCardPlacedOnBoard request.%22);%0A        final Card card = readCard(reader);%0A        final int x = reader.readInt();%0A        final int y = reader.readInt();%0A        log.info(%22Params: Card=%7B%7D, x=%7B%7D, y=%7B%7D%22, card, x, y);%0A        onCardPlacedOnBoard(card, x, y);%0A    %7D%0A%0A    /**%0A     * @param reader%0A     * @return%0A     * @throws IOException%0A     */%0A    private Card readCard(final IntReader reader) throws IOException %7B%0A        return this.cards.get(reader.readInt());
 %0A   

implement brotocol