croupier: Unify showPass and showTake in the HeartsGameComponent

There was a lot of repeated code, so I've merged it together into
something shorter. This should help me keep the two phases more
consistent when adjusting their look and feel.

Also including dartfmt on each .part.dart file as well

Change-Id: I3495b70314fb50c3438816cc5e9529d7f49ffab4
diff --git a/Makefile b/Makefile
index c508531..be9e164 100644
--- a/Makefile
+++ b/Makefile
@@ -20,12 +20,13 @@
 packages: pubspec.yaml
 	pub upgrade
 
-DART_LIB_FILES := $(shell find lib -name *.dart ! -name *.part.dart)
+DART_LIB_FILES_ALL := $(shell find lib -name *.dart)
+DART_TEST_FILES_ALL := $(shell find test -name *.dart)
 DART_TEST_FILES := $(shell find test -name *.dart ! -name *.part.dart)
 
 .PHONY: dartfmt
 dartfmt:
-	dartfmt -w $(DART_LIB_FILES) $(DART_TEST_FILES)
+	dartfmt -w $(DART_LIB_FILES_ALL) $(DART_TEST_FILES_ALL)
 
 .PHONY: lint
 lint: packages
diff --git a/lib/components/card_collection.dart b/lib/components/card_collection.dart
index 7f89781..df7e295 100644
--- a/lib/components/card_collection.dart
+++ b/lib/components/card_collection.dart
@@ -35,7 +35,7 @@
   final bool faceUp;
   final AcceptCb acceptCallback;
   final bool dragChildren;
-  final DropType acceptType;
+  final DropType _acceptType;
   final Comparator<logic_card.Card> comparator;
   final double width;
   final double height;
@@ -45,13 +45,14 @@
   final Color _altColor;
   final double rotation; // This angle is in radians.
 
+  DropType get acceptType => _acceptType ?? DropType.none;
   Color get backgroundColor => _backgroundColor ?? material.Colors.grey[500];
   Color get altColor => _altColor ?? material.Colors.grey[500];
 
   CardCollectionComponent(
       this.navigator, this.cards, this.faceUp, this.orientation,
       {this.dragChildren: false,
-      this.acceptType: DropType.none,
+      DropType acceptType,
       this.acceptCallback: null,
       this.comparator: null,
       this.width: DEFAULT_WIDTH,
@@ -61,7 +62,8 @@
       Color backgroundColor,
       Color altColor,
       this.rotation: 0.0})
-      : _backgroundColor = backgroundColor,
+      : _acceptType = acceptType,
+        _backgroundColor = backgroundColor,
         _altColor = altColor;
 
   CardCollectionComponentState createState() =>
@@ -336,6 +338,9 @@
               width: this.desiredWidth,
               child: wrapCards(cardComponents));
         });
+      default:
+        assert(false);
+        return null;
     }
   }
 }
diff --git a/lib/components/game.dart b/lib/components/game.dart
index 145c079..1c89bce 100644
--- a/lib/components/game.dart
+++ b/lib/components/game.dart
@@ -9,7 +9,7 @@
 import '../logic/hearts/hearts.dart' show HeartsGame, HeartsPhase, HeartsType;
 import 'board.dart' show HeartsBoard;
 import 'card_collection.dart'
-    show CardCollectionComponent, DropType, Orientation;
+    show CardCollectionComponent, DropType, Orientation, AcceptCb;
 
 import 'package:sky/widgets_next.dart';
 import 'package:sky/material.dart' as material;
diff --git a/lib/components/hearts/hearts.part.dart b/lib/components/hearts/hearts.part.dart
index 3419ba9..82d0e6e 100644
--- a/lib/components/hearts/hearts.part.dart
+++ b/lib/components/hearts/hearts.part.dart
@@ -5,7 +5,8 @@
 part of game_component;
 
 class HeartsGameComponent extends GameComponent {
-  HeartsGameComponent(NavigatorState navigator, Game game, NoArgCb cb, {double width, double height})
+  HeartsGameComponent(NavigatorState navigator, Game game, NoArgCb cb,
+      {double width, double height})
       : super(navigator, game, cb, width: width, height: height);
 
   HeartsGameComponentState createState() => new HeartsGameComponentState();
@@ -55,6 +56,8 @@
         passingCards2.add(card);
       } else if (dest == passingCards3 && passingCards3.length == 0) {
         passingCards3.add(card);
+      } else {
+        assert("Unknown destination pile dest" == true);
       }
     });
   }
@@ -128,7 +131,6 @@
       } else {
         print("You can't do that! ${reason}");
         game.debugString = reason;
-
       }
     });
   }
@@ -145,10 +147,10 @@
       child: new Flex([
         new Flexible(flex: 1, child: new Text('P${config.game.playerNumber}')),
         new Flexible(
-            flex: 5, child: _makeButton('Switch Player', _switchPlayersCallback)),
-        new Flexible(
             flex: 5,
-            child: _makeButton('Switch View', _switchViewCallback)),
+            child: _makeButton('Switch Player', _switchPlayersCallback)),
+        new Flexible(
+            flex: 5, child: _makeButton('Switch View', _switchViewCallback)),
         new Flexible(
             flex: 5, child: _makeButton('End Round', _endRoundDebugCallback)),
         new Flexible(flex: 4, child: _makeButton('Quit', _quitGameCallback))
@@ -227,7 +229,8 @@
 
   Widget showBoard() {
     HeartsGame game = config.game;
-    return new HeartsBoard(config.navigator, game, width: config.width, height: 0.80 * config.height);
+    return new HeartsBoard(config.navigator, game,
+        width: config.width, height: 0.80 * config.height);
   }
 
   Widget showPlay() {
@@ -276,8 +279,7 @@
 
     List<logic_card.Card> cards = game.cardCollections[p];
     CardCollectionComponent c = new CardCollectionComponent(
-        config.navigator,
-        cards, game.playerNumber == p, Orientation.suit,
+        config.navigator, cards, game.playerNumber == p, Orientation.suit,
         dragChildren: game.whoseTurn == p,
         comparator: _compareCards,
         width: config.width);
@@ -331,9 +333,70 @@
             justifyContent: FlexJustifyContent.spaceBetween));
   }
 
-  // the pass phase screen consists of 2 parts:
-  // The cards being passed + Pass button.
-  // The cards in your hand.
+  Widget _helpPassTake(
+      String name,
+      List<logic_card.Card> c1,
+      List<logic_card.Card> c2,
+      List<logic_card.Card> c3,
+      List<logic_card.Card> hand,
+      AcceptCb cb,
+      NoArgCb buttoncb) {
+    HeartsGame game = config.game as HeartsGame;
+
+    bool draggable = (cb != null);
+    bool completed = (buttoncb == null);
+
+    List<Widget> topCardWidgets = new List<Widget>();
+    topCardWidgets.add(_topCardWidget(c1, cb));
+    topCardWidgets.add(_topCardWidget(c2, cb));
+    topCardWidgets.add(_topCardWidget(c3, cb));
+    topCardWidgets.add(_makeButton(name, buttoncb, inactive: completed));
+
+    Color bgColor =
+        completed ? material.Colors.teal[600] : material.Colors.teal[500];
+
+    Widget topArea = new Container(
+        decoration: new BoxDecoration(backgroundColor: bgColor),
+        padding: new EdgeDims.all(10.0),
+        width: config.width,
+        child: new Flex(topCardWidgets,
+            justifyContent: FlexJustifyContent.spaceBetween));
+
+    Widget handArea = new CardCollectionComponent(
+        config.navigator, hand, true, Orientation.suit,
+        acceptCallback: cb,
+        dragChildren: draggable,
+        acceptType: draggable ? DropType.card : null,
+        comparator: _compareCards,
+        width: config.width,
+        backgroundColor: material.Colors.grey[500],
+        altColor: material.Colors.grey[700]);
+
+    return new Column(<Widget>[
+      topArea,
+      handArea,
+      new Text(game.debugString),
+      _makeDebugButtons()
+    ], justifyContent: FlexJustifyContent.spaceBetween);
+  }
+
+  Widget _topCardWidget(List<logic_card.Card> cards, AcceptCb cb) {
+    Widget ccc = new CardCollectionComponent(
+        config.navigator, cards, true, Orientation.show1,
+        acceptCallback: cb,
+        dragChildren: cb != null,
+        acceptType: cb != null ? DropType.card : null,
+        backgroundColor: material.Colors.white,
+        altColor: material.Colors.grey[200]);
+
+    if (cb == null) {
+      ccc = new Container(child: ccc);
+    }
+
+    return ccc;
+  }
+
+  // Pass Phase Screen: Show the cards being passed and the player's remaining cards.
   Widget showPass() {
     HeartsGame game = config.game as HeartsGame;
 
@@ -351,81 +414,18 @@
     });
 
     bool hasPassed = passCards.length != 0;
-    // TODO(alexfandrianto): You can pass as many times as you want... which is silly.
-    // Luckily, later passes shouldn't do anything.
 
-    List<Widget> passingCardWidgets = <Widget>[
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              passingCards1, true, Orientation.show1,
-              acceptCallback: _uiPassCardCallback,
-              dragChildren: !hasPassed,
-              acceptType: DropType.card,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200])),
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              passingCards2, true, Orientation.show1,
-              acceptCallback: _uiPassCardCallback,
-              dragChildren: !hasPassed,
-              acceptType: DropType.card,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200])),
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              passingCards3, true, Orientation.show1,
-              acceptCallback: _uiPassCardCallback,
-              dragChildren: !hasPassed,
-              acceptType: DropType.card,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200]))
-    ];
-    Widget passArea;
-    if (hasPassed) {
-      passArea = new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: material.Colors.teal[600]),
-          width: config.width,
-          child: new Flex(
-              passingCardWidgets
-                ..add(_makeButton("Pass", null, inactive: true)),
-              justifyContent: FlexJustifyContent.spaceBetween));
-    } else {
-      passArea = new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: material.Colors.teal[500]),
-          width: config.width,
-          child: new Flex(
-              passingCardWidgets
-                ..add(_makeButton("Pass", _makeGamePassCallback)),
-              justifyContent: FlexJustifyContent.spaceBetween));
-    }
-
-    // Return the pass cards and the player's remaining hand.
-    // (Also includes debug info)
-    return new Column(<Widget>[
-      passArea,
-      new CardCollectionComponent(
-              config.navigator,
-          remainingCards, true, Orientation.suit,
-          acceptCallback: _uiPassCardCallback,
-          dragChildren: !hasPassed,
-          acceptType: DropType.card,
-          comparator: _compareCards,
-          width: config.width,
-          backgroundColor: material.Colors.grey[500],
-          altColor: material.Colors.grey[700]),
-      new Text(game.debugString),
-      _makeDebugButtons()
-    ], justifyContent: FlexJustifyContent.spaceBetween);
+    return _helpPassTake(
+        "Pass",
+        passingCards1,
+        passingCards2,
+        passingCards3,
+        remainingCards,
+        _uiPassCardCallback,
+        hasPassed ? null : _makeGamePassCallback);
   }
 
+  // Take Phase Screen: Show the cards the player has received and the player's hand.
   Widget showTake() {
     HeartsGame game = config.game as HeartsGame;
 
@@ -442,60 +442,7 @@
     List<logic_card.Card> take3 =
         takeCards.length != 0 ? takeCards.sublist(2, 3) : [];
 
-    List<Widget> takeCardWidgets = <Widget>[
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              take1, true, Orientation.show1,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200])),
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              take2, true, Orientation.show1,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200])),
-      new Container(
-          margin: new EdgeDims.all(10.0),
-          child: new CardCollectionComponent(
-              config.navigator,
-              take3, true, Orientation.show1,
-              backgroundColor: material.Colors.white,
-              altColor: material.Colors.grey[200]))
-    ];
-    Widget takeArea;
-    if (hasTaken) {
-      takeArea = new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: material.Colors.teal[600]),
-          width: config.width,
-          child: new Flex(
-              takeCardWidgets..add(_makeButton("Take", null, inactive: true)),
-              justifyContent: FlexJustifyContent.spaceBetween));
-    } else {
-      takeArea = new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: material.Colors.teal[500]),
-          width: config.width,
-          child: new Flex(
-              takeCardWidgets..add(_makeButton("Take", _makeGameTakeCallback)),
-              justifyContent: FlexJustifyContent.spaceBetween));
-    }
-
-    // Return the passsed cards and the player's hand.
-    // (Also includes debug info)
-    return new Column(<Widget>[
-      takeArea,
-      new CardCollectionComponent(
-              config.navigator, playerCards, true, Orientation.suit,
-          comparator: _compareCards,
-          width: config.width,
-          backgroundColor: material.Colors.grey[500],
-          altColor: material.Colors.grey[700]),
-      new Text(game.debugString),
-      _makeDebugButtons()
-    ], justifyContent: FlexJustifyContent.spaceBetween);
+    return _helpPassTake("Take", take1, take2, take3, playerCards, null,
+        hasTaken ? null : _makeGameTakeCallback);
   }
 }
diff --git a/lib/components/proto/proto.part.dart b/lib/components/proto/proto.part.dart
index b0fa1f4..d840baf 100644
--- a/lib/components/proto/proto.part.dart
+++ b/lib/components/proto/proto.part.dart
@@ -5,7 +5,8 @@
 part of game_component;
 
 class ProtoGameComponent extends GameComponent {
-  ProtoGameComponent(NavigatorState navigator, Game game, NoArgCb cb, {double width, double height})
+  ProtoGameComponent(NavigatorState navigator, Game game, NoArgCb cb,
+      {double width, double height})
       : super(navigator, game, cb, width: width, height: height);
 
   ProtoGameComponentState createState() => new ProtoGameComponentState();
@@ -20,18 +21,24 @@
 
     for (int i = 0; i < 4; i++) {
       List<logic_card.Card> cards = config.game.cardCollections[i];
-      CardCollectionComponent c = new CardCollectionComponent(config.navigator, cards,
-          config.game.playerNumber == i, Orientation.horz,
-          dragChildren: true, acceptType: DropType.card, acceptCallback: _makeGameMoveCallback, width: config.width);
+      CardCollectionComponent c = new CardCollectionComponent(config.navigator,
+          cards, config.game.playerNumber == i, Orientation.horz,
+          dragChildren: true,
+          acceptType: DropType.card,
+          acceptCallback: _makeGameMoveCallback,
+          width: config.width);
       cardCollections.add(c); // flex
     }
 
     cardCollections.add(new Container(
         decoration: new BoxDecoration(
             backgroundColor: material.Colors.green[500], borderRadius: 5.0),
-        child: new CardCollectionComponent(config.navigator, config.game.cardCollections[4], true,
-            Orientation.show1,
-            dragChildren: true, acceptType: DropType.card, acceptCallback: _makeGameMoveCallback, width: config.width)));
+        child: new CardCollectionComponent(config.navigator,
+            config.game.cardCollections[4], true, Orientation.show1,
+            dragChildren: true,
+            acceptType: DropType.card,
+            acceptCallback: _makeGameMoveCallback,
+            width: config.width)));
 
     cardCollections.add(_makeDebugButtons());
 
@@ -63,4 +70,4 @@
       config.game.playerNumber = (config.game.playerNumber + 1) % 4;
     });
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/game/game_command.part.dart b/lib/logic/game/game_command.part.dart
index 240d0ba..aff0ddd 100644
--- a/lib/logic/game/game_command.part.dart
+++ b/lib/logic/game/game_command.part.dart
@@ -9,7 +9,8 @@
   final String data;
   final SimulLevel simultaneity;
 
-  GameCommand(this.phase, this.data, {this.simultaneity: SimulLevel.INDEPENDENT});
+  GameCommand(this.phase, this.data,
+      {this.simultaneity: SimulLevel.INDEPENDENT});
 
   // UNIMPLEMENTED
   bool canExecute(Game game);
@@ -27,4 +28,4 @@
   String toString() {
     return "${phase}|${data}";
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/game/game_log.part.dart b/lib/logic/game/game_log.part.dart
index 0764033..bda0af0 100644
--- a/lib/logic/game/game_log.part.dart
+++ b/lib/logic/game/game_log.part.dart
@@ -102,4 +102,4 @@
   void addToLogCb(List<GameCommand> log, GameCommand newCommand);
   List<GameCommand> updateLogCb(
       List<GameCommand> current, List<GameCommand> other, int mismatchIndex);
-}
\ No newline at end of file
+}
diff --git a/lib/logic/hearts/hearts_command.part.dart b/lib/logic/hearts/hearts_command.part.dart
index c8fb0df..3fe669c 100644
--- a/lib/logic/hearts/hearts_command.part.dart
+++ b/lib/logic/hearts/hearts_command.part.dart
@@ -6,27 +6,33 @@
 
 class HeartsCommand extends GameCommand {
   // Usually this constructor is used when reading from a log/syncbase.
-  HeartsCommand(String phase, String data) :
-    super(phase, data, simultaneity: computeSimul(phase));
+  HeartsCommand(String phase, String data)
+      : super(phase, data, simultaneity: computeSimul(phase));
 
-  HeartsCommand.fromCommand(String cmd) :
-    super(cmd.split("|")[0], cmd.split("|")[1], simultaneity: computeSimul(cmd.split("|")[0]));
+  HeartsCommand.fromCommand(String cmd)
+      : super(cmd.split("|")[0], cmd.split("|")[1],
+            simultaneity: computeSimul(cmd.split("|")[0]));
 
   // The following constructors are used for the player generating the HeartsCommand.
-  HeartsCommand.deal(int playerId, List<Card> cards) :
-    super("Deal", computeDeal(playerId, cards), simultaneity: SimulLevel.DEPENDENT);
+  HeartsCommand.deal(int playerId, List<Card> cards)
+      : super("Deal", computeDeal(playerId, cards),
+            simultaneity: SimulLevel.DEPENDENT);
 
-  HeartsCommand.pass(int senderId, List<Card> cards) :
-    super("Pass", computePass(senderId, cards), simultaneity: SimulLevel.INDEPENDENT);
+  HeartsCommand.pass(int senderId, List<Card> cards)
+      : super("Pass", computePass(senderId, cards),
+            simultaneity: SimulLevel.INDEPENDENT);
 
-  HeartsCommand.take(int takerId) :
-    super("Take", computeTake(takerId), simultaneity: SimulLevel.INDEPENDENT);
+  HeartsCommand.take(int takerId)
+      : super("Take", computeTake(takerId),
+            simultaneity: SimulLevel.INDEPENDENT);
 
-  HeartsCommand.play(int playerId, Card c) :
-    super("Play", computePlay(playerId, c), simultaneity: SimulLevel.TURN_BASED);
+  HeartsCommand.play(int playerId, Card c)
+      : super("Play", computePlay(playerId, c),
+            simultaneity: SimulLevel.TURN_BASED);
 
-  HeartsCommand.ready(int playerId) :
-    super("Ready", computeReady(playerId), simultaneity: SimulLevel.INDEPENDENT);
+  HeartsCommand.ready(int playerId)
+      : super("Ready", computeReady(playerId),
+            simultaneity: SimulLevel.INDEPENDENT);
 
   static SimulLevel computeSimul(String phase) {
     switch (phase) {
@@ -280,4 +286,4 @@
   bool transferCheck(List<Card> sender, List<Card> receiver, Card c) {
     return sender.contains(c);
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/hearts/hearts_game.part.dart b/lib/logic/hearts/hearts_game.part.dart
index ac9467c..4593066 100644
--- a/lib/logic/hearts/hearts_game.part.dart
+++ b/lib/logic/hearts/hearts_game.part.dart
@@ -472,4 +472,4 @@
     phase = HeartsPhase.Score;
     this.prepareScore();
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/hearts/hearts_log.part.dart b/lib/logic/hearts/hearts_log.part.dart
index 5f497e7..c619055 100644
--- a/lib/logic/hearts/hearts_log.part.dart
+++ b/lib/logic/hearts/hearts_log.part.dart
@@ -37,4 +37,4 @@
     assert(false);
     return current;
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/hearts/hearts_phase.part.dart b/lib/logic/hearts/hearts_phase.part.dart
index 79edc45..55894f5 100644
--- a/lib/logic/hearts/hearts_phase.part.dart
+++ b/lib/logic/hearts/hearts_phase.part.dart
@@ -4,4 +4,4 @@
 
 part of hearts;
 
-enum HeartsPhase { Deal, Pass, Take, Play, Score }
\ No newline at end of file
+enum HeartsPhase { Deal, Pass, Take, Play, Score }
diff --git a/lib/logic/hearts/hearts_type.part.dart b/lib/logic/hearts/hearts_type.part.dart
index be88e14..4c3e51f 100644
--- a/lib/logic/hearts/hearts_type.part.dart
+++ b/lib/logic/hearts/hearts_type.part.dart
@@ -4,4 +4,4 @@
 
 part of hearts;
 
-enum HeartsType { Player, Board }
\ No newline at end of file
+enum HeartsType { Player, Board }
diff --git a/lib/logic/proto/proto_command.part.dart b/lib/logic/proto/proto_command.part.dart
index 586d3e1..80cfeee 100644
--- a/lib/logic/proto/proto_command.part.dart
+++ b/lib/logic/proto/proto_command.part.dart
@@ -9,15 +9,15 @@
   ProtoCommand(String phase, String data) : super(phase, data);
 
   // The following constructors are used for the player generating the ProtoCommand.
-  ProtoCommand.deal(int playerId, List<Card> cards) :
-    super("Deal", computeDeal(playerId, cards));
+  ProtoCommand.deal(int playerId, List<Card> cards)
+      : super("Deal", computeDeal(playerId, cards));
 
   // TODO: receiverId is actually implied by the game round. So it may end up being removable.
-  ProtoCommand.pass(int senderId, int receiverId, List<Card> cards) :
-    super("Pass", computePass(senderId, receiverId, cards));
+  ProtoCommand.pass(int senderId, int receiverId, List<Card> cards)
+      : super("Pass", computePass(senderId, receiverId, cards));
 
-  ProtoCommand.play(int playerId, Card c) :
-    super("Play", computePlay(playerId, c));
+  ProtoCommand.play(int playerId, Card c)
+      : super("Play", computePlay(playerId, c));
 
   static String computeDeal(int playerId, List<Card> cards) {
     StringBuffer buff = new StringBuffer();
@@ -93,4 +93,4 @@
     sender.remove(c);
     receiver.add(c);
   }
-}
\ No newline at end of file
+}
diff --git a/lib/logic/proto/proto_game.part.dart b/lib/logic/proto/proto_game.part.dart
index a9878e4..2172750 100644
--- a/lib/logic/proto/proto_game.part.dart
+++ b/lib/logic/proto/proto_game.part.dart
@@ -46,4 +46,4 @@
 
   @override
   void triggerEvents() {}
-}
\ No newline at end of file
+}