package jrummikub.control; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import jrummikub.model.IHand; import jrummikub.model.ITable; import jrummikub.model.Position; import jrummikub.model.Stone; import jrummikub.model.StoneSet; import jrummikub.util.Connection; import jrummikub.util.Event; import jrummikub.util.IEvent; import jrummikub.util.IListener; import jrummikub.util.IListener1; import jrummikub.util.IListener2; import jrummikub.util.Pair; import jrummikub.view.IView; public class TurnControl { static class HandStonePositionComparator implements Comparator> { @Override public int compare(Pair pair1, Pair pair2) { Position pos1 = pair1.getSecond(), pos2 = pair2.getSecond(); if (pos1.getY() < pos2.getY()) { return -1; } else if (pos1.getY() > pos2.getY()) { return 1; } else { if (pos1.getX() < pos2.getX()) { return -1; } else if (pos1.getX() > pos2.getX()) { return 1; } else { return 0; } } } } private IHand hand; private ITable table; private ITurnTimer timer; private IView view; private List selectedStones = new ArrayList(); private Event endOfTurnEvent = new Event(); List connections = new ArrayList(); public TurnControl(IHand hand, ITable table, IView view) { this.hand = hand; this.table = table; this.view = view; this.timer = new TurnTimer(view); } /** Test only constructor **/ TurnControl(IHand hand, ITable table, IView view, ITurnTimer testTimer) { this.hand = hand; this.table = table; this.view = view; this.timer = testTimer; } public void startTurn() { IListener endOfTurnListener = new IListener() { @Override public void handle() { endOfTurn(); } }; connections.add(timer.getTimeRunOutEvent().add(endOfTurnListener)); connections.add(view.getPlayerPanel().getEndTurnEvent() .add(endOfTurnListener)); connections.add(view.getPlayerPanel().getHandPanel() .getStoneClickEvent().add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { stoneClick(stone, collect); } })); connections.add(view.getPlayerPanel().getHandPanel() .getRangeClickEvent().add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { handRangeClick(stone, collect); } })); connections.add(view.getTablePanel().getStoneCollectionPanel() .getStoneClickEvent().add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { collectionStoneClick(stone, collect); } })); connections.add(view.getTablePanel().getStoneCollectionPanel() .getSetClickEvent().add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { collectionSetClick(stone, collect); } })); connections.add(view.getTablePanel().getStoneClickEvent() .add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { stoneClick(stone, collect); } })); connections.add(view.getTablePanel().getSetClickEvent() .add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { tableSetClick(stone, collect); } })); connections.add(view.getTablePanel().getRangeClickEvent() .add(new IListener2() { @Override public void handle(Stone stone, Boolean collect) { tableRangeClick(stone, collect); } })); connections.add(view.getTablePanel().getClickEvent() .add(new IListener1() { @Override public void handle(Position pos) { tableClick(pos); } })); connections.add(view.getTablePanel().getLeftConnectorClickEvent() .add(new IListener1() { @Override public void handle(StoneSet set) { connectorClick(set, false); } })); connections.add(view.getTablePanel().getRightConnectorClickEvent() .add(new IListener1() { @Override public void handle(StoneSet set) { connectorClick(set, true); } })); connections.add(view.getPlayerPanel().getSortByGroupsEvent() .add(new IListener() { @Override public void handle() { sortByGroups(); } })); connections.add(view.getPlayerPanel().getSortByRunsEvent() .add(new IListener() { @Override public void handle() { sortByRuns(); } })); view.getPlayerPanel().getHandPanel().setStones(hand.clone()); view.enableStartTurnPanel(false); timer.startTimer(); } private void sortByRuns() { } private void sortByGroups() { } private void stoneClick(Stone stone, boolean collect) { if (collect) { if (!selectedStones.remove(stone)) { selectedStones.add(stone); } } else { selectedStones.clear(); selectedStones.add(stone); } view.setSelectedStones(selectedStones); } private void collectionStoneClick(Stone stone, boolean collect) { selectedStones.remove(stone); if (collect) { selectedStones.add(stone); } view.setSelectedStones(selectedStones); } private void collectionSetClick(Stone stone, Boolean collect) { selectedStones.clear(); view.setSelectedStones(selectedStones); } private void pickUpSelectedStones() { for (Stone stone : selectedStones) { hand.pickUp(stone); table.pickUpStone(stone); } } private void tableClick(Position position) { if (selectedStones.isEmpty()) { return; } pickUpSelectedStones(); table.drop(new StoneSet(selectedStones), new Position(position.getX() - selectedStones.size() * 0.5f, position.getY() - 0.5f)); selectedStones.clear(); view.getTablePanel().setStoneSets(table); view.getPlayerPanel().getHandPanel().setStones(hand); view.setSelectedStones(selectedStones); } private void tableSetClick(Stone stone, Boolean collect) { if (!collect) { selectedStones.clear(); } StoneSet selectedSet = table.findStoneSet(stone); for (Stone setStone : selectedSet) { selectedStones.remove(setStone); selectedStones.add(setStone); } view.setSelectedStones(selectedStones); } private void tableRangeClick(Stone stone, Boolean collect) { if (selectedStones.isEmpty()) { stoneClick(stone, collect); return; } Stone lastStone = selectedStones.get(selectedStones.size() - 1); StoneSet lastSet = table.findStoneSet(lastStone); StoneSet selectedSet = table.findStoneSet(stone); if (lastSet != selectedSet) { stoneClick(stone, collect); return; } List setStones = new ArrayList(); for (Stone s : selectedSet) { setStones.add(s); } int firstIndex = setStones.indexOf(lastStone); int lastIndex = setStones.indexOf(stone); if (firstIndex > lastIndex) { int temp = firstIndex; firstIndex = lastIndex; lastIndex = temp; } for (int i = firstIndex; i <= lastIndex; i++) { Stone s = setStones.get(i); selectedStones.remove(s); selectedStones.add(s); } view.setSelectedStones(selectedStones); } private void handRangeClick(Stone stone, Boolean collect) { if (selectedStones.isEmpty()) { stoneClick(stone, collect); return; } Stone lastStone = selectedStones.get(selectedStones.size() - 1); StoneSet lastSet = table.findStoneSet(lastStone); if (lastSet != null) { stoneClick(stone, collect); return; } List> handPairs = new ArrayList>(); for (Pair entry : hand) { handPairs.add(entry); } Collections.sort(handPairs, new HandStonePositionComparator()); List handStones = new ArrayList(); for (Pair entry : handPairs) { handStones.add(entry.getFirst()); } int firstIndex = handStones.indexOf(lastStone); int lastIndex = handStones.indexOf(stone); if (firstIndex > lastIndex) { int temp = firstIndex; firstIndex = lastIndex; lastIndex = temp; } for (int i = firstIndex; i <= lastIndex; i++) { Stone s = handStones.get(i); selectedStones.remove(s); selectedStones.add(s); } view.setSelectedStones(selectedStones); } private void connectorClick(StoneSet set, boolean right) { List stones = new LinkedList(); Position pos = table.getPosition(set); for (Stone stone : set) { stones.add(stone); } stones.removeAll(selectedStones); if (right) { Collections.reverse(stones); } pickUpSelectedStones(); StoneSet newSet = null; for (Stone stone : stones) { newSet = table.findStoneSet(stone); if (newSet != null) { break; } } if (newSet != null) { Position newPos = table.getPosition(newSet); table.pickUp(newSet); if (right) { StoneSet joinedSet = newSet.join(new StoneSet(selectedStones)); table.drop(joinedSet, newPos); } else { StoneSet joinedSet = new StoneSet(selectedStones).join(newSet); table.drop(joinedSet, new Position(newPos.getX() - selectedStones.size(), newPos.getY())); } } else { table.drop(new StoneSet(selectedStones), new Position(RoundControl.HAND_WIDTH-1, RoundControl.HAND_HEIGHT-1)); } selectedStones.clear(); view.getTablePanel().setStoneSets(table); view.getPlayerPanel().getHandPanel().setStones(hand); view.setSelectedStones(selectedStones); } private void endOfTurn() { timer.stopTimer(); endOfTurnEvent.emit(); for (Connection c : connections) { c.remove(); } view.setSelectedStones(new ArrayList()); } public IEvent getEndOfTurnEvent() { return endOfTurnEvent; } }