croupier: Improve the Status Bar

Make it glow orange if it is your turn.
It is red if you made a mistake.

There is also a trick number icon to show you the number of tricks
you've taken.

(The Take Trick button was modified for style purposes.)

Change-Id: I4df8f7ef176e01ea528e3632f3476cc5a6421f46
diff --git a/lib/components/hearts/hearts.part.dart b/lib/components/hearts/hearts.part.dart
index ec5cc00..18a09bd 100644
--- a/lib/components/hearts/hearts.part.dart
+++ b/lib/components/hearts/hearts.part.dart
@@ -362,25 +362,25 @@
     return config.croupier.settingsFromPlayerNumber(playerNumber)?.name;
   }
 
-  String _getStatus() {
+  HeartsStatus _getStatus() {
     HeartsGame game = config.game;
 
     String status;
+    bool isPlayer = false;
+    bool isError = false;
     switch (game.phase) {
       case HeartsPhase.Play:
         // Who's turn is it?
         String name = _getName(game.whoseTurn) ?? "Player ${game.whoseTurn}";
-        status = game.whoseTurn == game.playerNumber
-            ? "Your turn"
-            : "${name}'s turn";
+        isPlayer = game.whoseTurn == game.playerNumber;
+        status = isPlayer ? "Your turn" : "${name}'s turn";
 
         // Override if someone is taking a trick.
         if (game.allPlayed) {
           int winner = game.determineTrickWinner();
           String trickTaker = _getName(winner) ?? "Player ${winner}";
-          status = winner == game.playerNumber
-              ? "Your trick"
-              : "${trickTaker}'s trick";
+          isPlayer = winner == game.playerNumber;
+          status = isPlayer ? "Your trick" : "${trickTaker}'s trick";
         }
         break;
       case HeartsPhase.Pass:
@@ -390,6 +390,7 @@
           String name =
               _getName(game.passTarget) ?? "Player ${game.passTarget}";
           status = "Pass to ${name}";
+          isPlayer = true;
         }
         break;
       case HeartsPhase.Take:
@@ -399,6 +400,7 @@
           String name =
               _getName(game.takeTarget) ?? "Player ${game.takeTarget}";
           status = "Take from ${name}";
+          isPlayer = true;
         }
         break;
       default:
@@ -408,17 +410,36 @@
     // Override if there is a debug string.
     if (game.debugString != null) {
       status = game.debugString;
+      isError = true;
     }
 
-    return status;
+    return new HeartsStatus(status, isPlayer, isError);
+  }
+
+  Widget _buildNumTrickIcon() {
+    HeartsGame game = config.game;
+
+    int numTrickCards = game.cardCollections[
+        HeartsGame.OFFSET_TRICK + game.playerNumber].length;
+    int numTricks = numTrickCards ~/ 4;
+
+    String iconName = "image/filter_9_plus";
+    if (numTricks == 0) {
+      iconName = "image/filter_none";
+    } else if (numTricks <= 9) {
+      iconName = "image/filter_${numTricks}";
+    }
+
+    return new Icon(icon: iconName);
   }
 
   Widget _buildStatusBar() {
     HeartsGame game = config.game;
 
     List<Widget> statusBarWidgets = new List<Widget>();
+    HeartsStatus status = _getStatus();
     statusBarWidgets.add(new Flexible(
-        flex: 1, child: new Text(_getStatus(), style: style.Text.largeStyle)));
+        flex: 1, child: new Text(status.text, style: style.Text.largeStyle)));
 
     switch (game.phase) {
       case HeartsPhase.Play:
@@ -432,11 +453,13 @@
                 });
               },
                   child: new Container(
-                      decoration: style.Box.liveBackground,
+                      decoration: style.Box.brightBackground,
+                      margin: style.Spacing.smallPaddingSide,
                       padding: style.Spacing.smallPadding,
                       child: new Text("Take Cards",
                           style: style.Text.largeStyle)))));
         }
+        statusBarWidgets.add(_buildNumTrickIcon());
         statusBarWidgets
             .add(new IconButton(icon: "action/swap_vert", onPressed: () {
           setState(() {
@@ -471,10 +494,17 @@
         break;
     }
 
+    BoxDecoration decoration = style.Box.background;
+    if (status.isPlayer) {
+      decoration = style.Box.liveBackground;
+    }
+    if (status.isError) {
+      decoration = style.Box.errorBackground;
+    }
+
     return new Container(
         padding: new EdgeDims.all(10.0),
-        decoration:
-            new BoxDecoration(backgroundColor: style.theme.primaryColor),
+        decoration: decoration,
         child: new Row(statusBarWidgets,
             justifyContent: FlexJustifyContent.spaceBetween));
   }
@@ -507,8 +537,7 @@
 
     if (_showSplitView) {
       cardCollections.add(new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: style.theme.primaryColor),
+          decoration: style.Box.background,
           child: new Column([_buildFullMiniBoard(), _buildStatusBar()])));
     } else {
       Widget playArea = new Container(
@@ -527,8 +556,7 @@
                       : Colors.grey[600])));
 
       cardCollections.add(new Container(
-          decoration:
-              new BoxDecoration(backgroundColor: style.theme.primaryColor),
+          decoration: style.Box.background,
           child: new BlockBody([_buildStatusBar(), playArea])));
     }
 
@@ -852,3 +880,11 @@
     return new Flexible(flex: 1, child: dragTarget);
   }
 }
+
+class HeartsStatus {
+  final String text;
+  final bool isPlayer;
+  final bool isError;
+
+  const HeartsStatus(this.text, this.isPlayer, this.isError);
+}
diff --git a/lib/styles/common.dart b/lib/styles/common.dart
index ac4fd52..5fec982 100644
--- a/lib/styles/common.dart
+++ b/lib/styles/common.dart
@@ -5,20 +5,18 @@
 import 'package:flutter/material.dart';
 
 class Text {
-  static final Color secondaryTextColor = Colors.grey[500];
-  static final Color errorTextColor = Colors.red[500];
   static final TextStyle titleStyle = new TextStyle(fontSize: 18.0);
   static final TextStyle subtitleStyle =
       new TextStyle(fontSize: 12.0, color: secondaryTextColor);
   static final TextStyle liveNow =
       new TextStyle(fontSize: 12.0, color: theme.accentColor);
-  static final TextStyle error = new TextStyle(color: errorTextColor);
+  static final TextStyle error = new TextStyle(color: errorColor);
   static final TextStyle hugeStyle = new TextStyle(fontSize: 32.0);
   static final TextStyle hugeRedStyle =
-      new TextStyle(fontSize: 32.0, color: errorTextColor);
+      new TextStyle(fontSize: 32.0, color: errorColor);
   static final TextStyle largeStyle = new TextStyle(fontSize: 24.0);
   static final TextStyle largeRedStyle =
-      new TextStyle(fontSize: 24.0, color: errorTextColor);
+      new TextStyle(fontSize: 24.0, color: errorColor);
   static final TextStyle splash =
       new TextStyle(fontSize: 16.0, color: Colors.white);
 }
@@ -29,6 +27,8 @@
 }
 
 class Spacing {
+  static final EdgeDims smallPaddingSide =
+      new EdgeDims.symmetric(horizontal: 5.0);
   static final EdgeDims smallPadding = new EdgeDims.all(5.0);
   static final EdgeDims normalPadding = new EdgeDims.all(10.0);
 }
@@ -38,11 +38,19 @@
       border: new Border.all(color: theme.accentColor), borderRadius: 2.0);
   static final BoxDecoration liveBackground =
       new BoxDecoration(backgroundColor: theme.accentColor);
+  static final BoxDecoration background =
+      new BoxDecoration(backgroundColor: theme.primaryColor);
+  static final BoxDecoration brightBackground =
+      new BoxDecoration(backgroundColor: theme.primarySwatch[100]);
+  static final BoxDecoration errorBackground =
+      new BoxDecoration(backgroundColor: errorColor);
   static final BoxDecoration border = new BoxDecoration(
       border: new Border.all(color: theme.primaryColor), borderRadius: 2.0);
   static final BoxDecoration borderInactive = new BoxDecoration(
       border: new Border.all(color: Colors.grey[300]), borderRadius: 2.0);
 }
 
+Color secondaryTextColor = Colors.grey[500];
+Color errorColor = Colors.red[500];
 ThemeData theme = new ThemeData(
     primarySwatch: Colors.blueGrey, accentColor: Colors.orangeAccent[700]);
diff --git a/manifest.yaml b/manifest.yaml
index 9a936d1..98c5ab0 100644
--- a/manifest.yaml
+++ b/manifest.yaml
@@ -6,6 +6,17 @@
   - name: av/play_arrow
   - name: action/swap_vert
   - name: hardware/tablet
+  - name: image/filter_none
+  - name: image/filter_1
+  - name: image/filter_2
+  - name: image/filter_3
+  - name: image/filter_4
+  - name: image/filter_5
+  - name: image/filter_6
+  - name: image/filter_7
+  - name: image/filter_8
+  - name: image/filter_9
+  - name: image/filter_9_plus
   - name: navigation/arrow_back
   - name: navigation/arrow_forward
   - name: navigation/menu