Index: .settings/org.eclipse.jdt.core.prefs
===================================================================
--- .settings/org.eclipse.jdt.core.prefs	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
+++ .settings/org.eclipse.jdt.core.prefs	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -0,0 +1,5 @@
+#Tue Jan 18 16:04:51 EST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
Index: AndroidManifest.xml
===================================================================
--- AndroidManifest.xml	(revision 9b1f66b267b63dfffb82b32a8db972f27510d8e5)
+++ AndroidManifest.xml	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -5,5 +5,5 @@
       android:versionName="1.0">
     <application android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:name=".advancewars"
+        <activity android:name=".Game"
                   android:label="@string/app_name">
             <intent-filter>
Index: res/layout/main.xml
===================================================================
--- res/layout/main.xml	(revision 9b1f66b267b63dfffb82b32a8db972f27510d8e5)
+++ res/layout/main.xml	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-<TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" 
-    android:text="@string/hello"
-    />
-</LinearLayout>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="fill_parent">
+	<com.example.advancewars.GameView android:id="@+id/lunar"
+		android:layout_width="fill_parent"
+		android:layout_height="fill_parent" /> 
+	<RelativeLayout android:layout_width="fill_parent"
+		android:layout_height="fill_parent">
+		<TextView android:id="@+id/text" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:textColor="#88ffffff" android:textSize="24sp" /> 
+  	</RelativeLayout>
+</FrameLayout>
Index: res/values/strings.xml
===================================================================
--- res/values/strings.xml	(revision 9b1f66b267b63dfffb82b32a8db972f27510d8e5)
+++ res/values/strings.xml	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -3,3 +3,4 @@
     <string name="hello">Hello World, advancewars!</string>
     <string name="app_name"></string>
+    <string name="menu_exit">Exit</string>
 </resources>
Index: src/com/example/advancewars/AppState.java
===================================================================
--- src/com/example/advancewars/AppState.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
+++ src/com/example/advancewars/AppState.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -0,0 +1,9 @@
+package com.example.advancewars;
+
+public enum AppState {
+	LOSE,
+	PAUSE,
+	READY,
+	RUNNING,
+	WIN
+}
Index: src/com/example/advancewars/Game.java
===================================================================
--- src/com/example/advancewars/Game.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
+++ src/com/example/advancewars/Game.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -0,0 +1,134 @@
+package com.example.advancewars;
+
+import com.example.advancewars.R;
+import com.example.advancewars.GameView;
+import com.example.advancewars.GameView.DrawingThread;
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.TextView;
+import java.io.*;
+
+public class Game extends Activity {
+    private static final int MENU_EXIT = 1;
+    private static final int MENU_NEW = 2;
+    
+    public enum State{BUST, ACTIVE, DOUBLEDOWN};
+
+    /** A handle to the thread that's actually running the animation. */
+    public DrawingThread mThread;
+
+    /** A handle to the View in which the game is running. */
+    private GameView mGameView;
+    
+    /**
+     * Invoked during init to give the Activity a chance to set up its Menu.
+     * 
+     * @param menu the Menu to which entries may be added
+     * @return true
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        menu.add(0, MENU_EXIT, 0, R.string.menu_exit);
+        return true;
+    }
+
+    /**
+     * Invoked when the user selects an item from the Menu.
+     * 
+     * @param item the Menu entry which was selected
+     * @return true if the Menu item was legit (and we consumed it), false
+     *         otherwise
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case MENU_EXIT:
+            	this.finish();
+            	break;
+            case MENU_NEW:
+            	if(mThread.mGameState == GameState.COMP_TURN)
+            		mGameView.newRound();
+            	break;
+        }
+
+        return true;
+    }
+
+    /**
+     * Invoked when the Activity is created.
+     * 
+     * @param savedInstanceState a Bundle containing state saved from a previous
+     *        execution, or null if this is a new execution
+     */
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+    	Log.w("Blackjack", "We're inside onCreate");
+    	
+        super.onCreate(savedInstanceState);
+        
+        Log.w("Blackjack", "the super constructor was called successfully");
+
+        // turn off the window's title bar
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        // tell system to use the layout defined in our XML file
+        setContentView(R.layout.main);
+
+        mGameView = (GameView) findViewById(R.id.lunar);
+        mThread = mGameView.getThread();
+
+        mGameView.setTextView((TextView) findViewById(R.id.text));
+
+        if (savedInstanceState == null) {	// we were just launched: set up a new game
+        	Log.w("Blackjack", "SIS is null");
+        	
+        	mThread.setState(AppState.RUNNING);
+        } else {
+            Log.w("Blackjack", "SIS is nonnull");
+            
+            mThread.setState(AppState.RUNNING);
+            
+            mGameView.getThread().mGameState = (GameState)savedInstanceState.getSerializable("gameState");
+            
+		    mGameView.getThread().mPlayerWins = savedInstanceState.getInt("playerWins");
+		    mGameView.getThread().mPlayerLosses = savedInstanceState.getInt("playerLosses");
+        }
+    }
+
+    /**
+     * Invoked when the Activity loses user focus.
+     */
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mGameView.getThread().pause(); // pause game when Activity pauses
+    }
+
+    /**
+     * Notification that something is about to happen, to give the Activity a
+     * chance to save state.
+     * 
+     * @param outState a Bundle into which this Activity should save its state
+     */
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+    	outState.putSerializable("gameState", mGameView.getThread().mGameState);
+	    outState.putSerializable("playerWins", mGameView.getThread().mPlayerWins);
+	    outState.putSerializable("playerLosses", mGameView.getThread().mPlayerLosses);
+	    
+        super.onSaveInstanceState(outState);
+        Log.w("Blackjack", "onSaveInstanceState called");
+    }
+    
+    @Override
+    protected void onStop() {
+    	System.exit(1);
+    	super.onStop();
+    }
+}
Index: src/com/example/advancewars/GameState.java
===================================================================
--- src/com/example/advancewars/GameState.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
+++ src/com/example/advancewars/GameState.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -0,0 +1,6 @@
+package com.example.advancewars;
+
+public enum GameState {
+	YOUR_TURN,
+	COMP_TURN
+}
Index: src/com/example/advancewars/GameView.java
===================================================================
--- src/com/example/advancewars/GameView.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
+++ src/com/example/advancewars/GameView.java	(revision 5d9e7bb16ff8265f4388276fc3d0d3e4f9f78923)
@@ -0,0 +1,454 @@
+package com.example.advancewars;
+
+import java.util.*;
+
+import android.content.Context;
+import android.graphics.*;
+import android.os.*;
+import android.view.*;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.TextView;
+
+/**
+ * View that draws, takes keystrokes, etc. for a simple LunarLander game.
+ * 
+ * Has a mode which RUNNING, PAUSED, etc. Has a x, y, dx, dy, ... capturing the
+ * current ship physics. All x/y etc. are measured with (0,0) at the lower left.
+ * updatePhysics() advances the physics based on realtime. draw() renders the
+ * ship, and does an invalidate() to prompt another draw() as soon as possible
+ * by the system.
+ */
+class GameView extends SurfaceView implements SurfaceHolder.Callback {
+	
+    class DrawingThread extends Thread {        
+        public AppState mAppState;
+        public GameState mGameState;
+
+        /*
+         * UI constants (i.e. the speed & fuel bars)
+         */
+        public static final int UI_BAR = 100; // width of the bar(s)
+        public static final int UI_BAR_HEIGHT = 10; // height of the bar(s)
+
+        /*
+         * Member (state) fields
+         */
+
+        private int mCanvasHeight = 1;
+        private int mCanvasWidth = 1;
+        public int mPlayerWins = 0, mPlayerLosses = 0;
+
+        /** Message handler used by thread to interact with TextView */
+        private Handler mHandler;
+
+        /** Used to figure out elapsed time between frames */
+        private long mLastTime;
+
+        /** Paint to draw the lines on screen. */
+        private Paint mLinePaint, mTextPaint, mButtonPaint;
+
+        /** Indicate whether the surface has been created & is ready to draw */
+        private boolean mRun = false;
+
+        /** Handle to the surface manager object we interact with */
+        private SurfaceHolder mSurfaceHolder;
+        
+        public DrawingThread(SurfaceHolder surfaceHolder, Context context,
+                Handler handler) {
+            // get handles to some important objects
+            mSurfaceHolder = surfaceHolder;
+            mHandler = handler;
+            mContext = context;
+
+            // Initialize paints for speedometer
+            mLinePaint = new Paint();
+            mLinePaint.setAntiAlias(true);
+            mLinePaint.setARGB(255, 0, 255, 0);
+
+            mTextPaint = new Paint();
+            mTextPaint.setAntiAlias(true);
+            mTextPaint.setARGB(255, 255, 255, 255);
+            mTextPaint.setTextSize(12);
+            
+            mButtonPaint = new Paint();
+            mButtonPaint.setAntiAlias(true);
+            mButtonPaint.setARGB(255, 0, 0, 0);
+            mButtonPaint.setTextSize(20);
+            mButtonPaint.setTextAlign(Paint.Align.CENTER);
+            
+            mGameState = GameState.YOUR_TURN;
+        }
+        
+        /**
+         * Starts the game, setting parameters for the current difficulty.
+         */
+        // I don't think this gets called now. maybe we should call it in the thread constructor
+        public void doStart() {
+            synchronized (mSurfaceHolder) {
+                mLastTime = System.currentTimeMillis() + 100;
+                setState(AppState.RUNNING);
+                Log.i("Blackjack", "Player's turn starting now");
+                mGameState = GameState.YOUR_TURN;
+            }
+        }
+
+        /**
+         * Pauses the physics update & animation.
+         */
+        public void pause() {
+            synchronized (mSurfaceHolder) {
+                if (mAppState == AppState.RUNNING) setState(AppState.PAUSE);
+            }
+        }
+
+        @Override
+        public void run() {
+            while (mRun) {
+                Canvas c = null;
+                try {
+                    c = mSurfaceHolder.lockCanvas(null);
+                    synchronized(mSurfaceHolder) {
+                        if(mAppState == AppState.RUNNING)
+                        	updatePhysics();
+                        doDraw(c);
+                    }
+                } finally {
+                    // do this in a finally so that if an exception is thrown
+                    // during the above, we don't leave the Surface in an
+                    // inconsistent state
+                    if (c != null) {
+                        mSurfaceHolder.unlockCanvasAndPost(c);
+                    }
+                }
+            }
+        }
+
+        /**
+         * Used to signal the thread whether it should be running or not.
+         * Passing true allows the thread to run; passing false will shut it
+         * down if it's already running. Calling start() after this was most
+         * recently called with false will result in an immediate shutdown.
+         * 
+         * @param b true to run, false to shut down
+         */
+        public void setRunning(boolean b) {
+            mRun = b;
+        }
+
+        /**
+         * Sets the game mode. That is, whether we are running, paused, in the
+         * failure state, in the victory state, etc.
+         * 
+         * @see #setState(int, CharSequence)
+         * @param mode one of the STATE_* constants
+         */
+        public void setState(AppState state) {
+            synchronized (mSurfaceHolder) {
+                setState(state, null);
+            }
+        }
+        
+        public void setGameState(GameState state) {
+            synchronized (mSurfaceHolder) {
+                mGameState = state;
+            }
+        }
+
+        /**
+         * Sets the game mode. That is, whether we are running, paused, in the
+         * failure state, in the victory state, etc.
+         * 
+         * @param mode one of the STATE_* constants
+         * @param message string to add to screen or null
+         */
+        public void setState(AppState mode, CharSequence message) {
+            /*
+             * This method optionally can cause a text message to be displayed
+             * to the user when the mode changes. Since the View that actually
+             * renders that text is part of the main View hierarchy and not
+             * owned by this thread, we can't touch the state of that View.
+             * Instead we use a Message + Handler to relay commands to the main
+             * thread, which updates the user-text View.
+             */
+            synchronized (mSurfaceHolder) {
+            	mAppState = mode;
+
+                if (mAppState == AppState.RUNNING) {
+                    Message msg = mHandler.obtainMessage();
+                    Bundle b = new Bundle();
+                    b.putString("text", "");
+                    b.putInt("viz", GameView.INVISIBLE);
+                    msg.setData(b);
+                    mHandler.sendMessage(msg);
+                } else {
+                    CharSequence str = "";
+                    str = "Mode probably changed";
+
+                    if (message != null) {
+                        str = message + "\n" + str;
+                    }
+
+                    Message msg = mHandler.obtainMessage();
+                    Bundle b = new Bundle();
+                    b.putString("text", str.toString());
+                    b.putInt("viz", GameView.VISIBLE);
+                    msg.setData(b);
+                    //mHandler.sendMessage(msg);
+                }
+            }
+        }
+        
+        /* Callback invoked when the surface dimensions change. */
+        public void setSurfaceSize(int width, int height) {
+            // synchronized to make sure these all change atomically
+            synchronized (mSurfaceHolder) {
+                mCanvasWidth = width;
+                mCanvasHeight = height;
+                
+                Log.i("Blackjack", "width: "+mCanvasWidth+", height: "+mCanvasHeight);
+            }
+        }
+
+        /**
+         * Resumes from a pause.
+         */
+        public void unpause() {
+            // Move the real time clock up to now
+            synchronized (mSurfaceHolder) {
+                mLastTime = System.currentTimeMillis() + 100;
+            }
+            setState(AppState.RUNNING);
+        }
+
+        /**
+         * Handles a key-down event.
+         * 
+         * @param keyCode the key that was pressed
+         * @param msg the original event object
+         * @return true
+         */
+        boolean doKeyDown(int keyCode, KeyEvent msg) {
+            synchronized (mSurfaceHolder) {
+                boolean okStart = false;
+                if (keyCode == KeyEvent.KEYCODE_DPAD_UP) okStart = true;
+                if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) okStart = true;
+                if (keyCode == KeyEvent.KEYCODE_S) okStart = true;
+
+                if (okStart
+                        && (mAppState == AppState.READY || mAppState == AppState.LOSE || mAppState == AppState.WIN)) {
+                    // ready-to-start -> start
+                    doStart();
+                    return true;
+                } else if (mAppState == AppState.PAUSE && okStart) {
+                    // paused -> running
+                    unpause();
+                    return true;
+                } else if (mAppState == AppState.RUNNING) {
+                    return true;
+                }
+
+                return false;
+            }
+        }
+
+        /**
+         * Handles a key-up event.
+         * 
+         * @param keyCode the key that was pressed
+         * @param msg the original event object
+         * @return true if the key was handled and consumed, or else false
+         */
+        boolean doKeyUp(int keyCode, KeyEvent msg) {
+            boolean handled = false;
+
+            synchronized (mSurfaceHolder) {
+                if (mAppState == AppState.RUNNING) {
+                    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
+                            || keyCode == KeyEvent.KEYCODE_SPACE) {
+                        handled = true;
+                    } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT
+                            || keyCode == KeyEvent.KEYCODE_Q
+                            || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT
+                            || keyCode == KeyEvent.KEYCODE_W) {
+                        handled = true;
+                    }
+                }
+            }
+
+            return handled;
+        }
+
+        /**
+         * Draws the ship, fuel/speed bars, and background to the provided
+         * Canvas.
+         */
+        private void doDraw(Canvas canvas) {
+        	canvas.drawColor(Color.BLACK);
+        	
+        	mTextPaint.setTextSize(12);
+        	Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
+        	
+        	String text = "Your Total: ";
+        	canvas.drawText(text, 40-mTextPaint.measureText(text)/2, 450-(metrics.ascent+metrics.descent)/2, mTextPaint);
+        	
+        	text = "Dealer Total: ";
+        	canvas.drawText(text, 125-mTextPaint.measureText(text)/2, 450-(metrics.ascent+metrics.descent)/2, mTextPaint);
+        	
+        	text = mPlayerWins+" wins - "+mPlayerLosses+" losses";
+        	canvas.drawText(text, 270-mTextPaint.measureText(text)/2, 450-(metrics.ascent+metrics.descent)/2, mTextPaint);
+        }
+
+        /**
+         * Figures the lander state (x, y, fuel, ...) based on the passage of
+         * realtime. Does not invalidate(). Called at the start of draw().
+         * Detects the end-of-game and sets the UI to the next state.
+         */
+        private void updatePhysics() {
+            long now = System.currentTimeMillis();
+
+            // Do nothing if mLastTime is in the future.
+            // This allows the game-start to delay the start of the physics
+            // by 100ms or whatever.
+            if (mLastTime > now) return;
+            
+            // DO SHIT HERE
+
+            mLastTime = now+50;
+        }
+    }
+
+    /** Handle to the application context, used to e.g. fetch Drawables. */
+    private Context mContext;
+
+    /** Pointer to the text view to display "Paused.." etc. */
+    private TextView mStatusText;
+
+    /** The thread that actually draws the animation */
+    private DrawingThread thread;
+
+    public GameView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        // register our interest in hearing about changes to our surface
+        SurfaceHolder holder = getHolder();
+        holder.addCallback(this);
+
+        // create thread only; it's started in surfaceCreated()
+        thread = new DrawingThread(holder, context, new Handler() {
+            @Override
+            public void handleMessage(Message m) {
+                mStatusText.setVisibility(m.getData().getInt("viz"));
+                mStatusText.setText(m.getData().getString("text"));
+            }
+        });
+
+        setFocusable(true); // make sure we get key events
+    }
+    
+    public void newRound() {        
+        thread.mGameState = GameState.YOUR_TURN;        
+    }
+
+    @Override public boolean onTouchEvent(MotionEvent event) {
+    	Log.i("Blackjack", "Detected touch event");
+    	
+    	if(event.getAction() == MotionEvent.ACTION_UP) {
+    		Log.i("Blackjack", "Detected UP touch action");
+    		switch(thread.mGameState) {
+    		case YOUR_TURN:
+    			Log.i("Blackjack", "Player's turn");
+    			break;
+    		case COMP_TURN:
+    			Log.i("Blackjack", "Computer's turn");
+    			break;
+    		}
+    	}else if(event.getAction() == MotionEvent.ACTION_DOWN) {
+	    	
+    	}
+        
+        return true;
+    }
+    
+    /**
+     * Fetches the animation thread corresponding to this LunarView.
+     * 
+     * @return the animation thread
+     */
+    public DrawingThread getThread() {
+        return thread;
+    }
+
+    /**
+     * Standard override to get key-press events.
+     */
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent msg) {
+        return thread.doKeyDown(keyCode, msg);
+    }
+
+    /**
+     * Standard override for key-up. We actually care about these, so we can
+     * turn off the engine or stop rotating.
+     */
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent msg) {
+        return thread.doKeyUp(keyCode, msg);
+    }
+
+    /**
+     * Standard window-focus override. Notice focus lost so we can pause on
+     * focus lost. e.g. user switches to take a call.
+     */
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (!hasWindowFocus) thread.pause();
+    }
+
+    /**
+     * Installs a pointer to the text view used for messages.
+     */
+    public void setTextView(TextView textView) {
+        mStatusText = textView;
+    }
+
+    /* Callback invoked when the surface dimensions change. */
+    public void surfaceChanged(SurfaceHolder holder, int format, int width,
+            int height) {
+        thread.setSurfaceSize(width, height);
+    }
+
+    /*
+     * Callback invoked when the Surface has been created and is ready to be
+     * used.
+     */
+    public void surfaceCreated(SurfaceHolder holder) {
+        // start the thread here so that we don't busy-wait in run()
+        // waiting for the surface to be created
+        thread.setRunning(true);
+        
+        //if(thread.mAppState == AppState.PAUSE)
+        	//thread.unpause();
+        //else
+        	thread.start();
+    }
+
+    /*
+     * Callback invoked when the Surface has been destroyed and must no longer
+     * be touched. WARNING: after this method returns, the Surface/Canvas must
+     * never be touched again!
+     */
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // we have to tell thread to shut down & wait for it to finish, or else
+        // it might touch the Surface after we return and explode
+        boolean retry = true;
+        thread.setRunning(false);
+        while (retry) {
+            try {
+                thread.join();
+                retry = false;
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+}
