araepm: cosmetic changes for october 2014 demo
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7dc966e..d5f0686 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,6 +15,7 @@
         android:theme="@style/AppTheme" >
         <activity
             android:name="com.projectara.araepm.MainActivity"
+            android:screenOrientation="portrait"
             android:label="@string/app_name" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/res/anim/leftside_move_leftside.xml b/res/anim/leftside_move_leftside.xml
index 411b6f9..77ab5e3 100644
--- a/res/anim/leftside_move_leftside.xml
+++ b/res/anim/leftside_move_leftside.xml
@@ -1,11 +1,14 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-
-   <translate
-        android:fromXDelta="0%p"
-        android:toXDelta="-19%p"
-        android:duration="800" />
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="true"

+    android:fillEnabled="true"

+    android:fillBefore="false">

+

+   <translate

+      

+        android:fromXDelta="0%p"

+        android:toXDelta="-31"

+        android:duration="800" />

 </set>
\ No newline at end of file
diff --git a/res/anim/leftside_move_rightside.xml b/res/anim/leftside_move_rightside.xml
index ae45492..2744cbf 100644
--- a/res/anim/leftside_move_rightside.xml
+++ b/res/anim/leftside_move_rightside.xml
@@ -1,11 +1,13 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-    <translate
-        android:duration="800"
-        android:fromXDelta="0%p"
-        android:toXDelta="19%p" >
-    </translate>
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="true"

+    android:fillEnabled="true"

+    android:fillBefore="false">

+    <translate

+        android:duration="800"

+        android:fromXDelta="0%p"

+        android:toXDelta="31" >

+    </translate>

 </set>
\ No newline at end of file
diff --git a/res/anim/move.xml b/res/anim/move.xml
index 87229e0..e352bfe 100644
--- a/res/anim/move.xml
+++ b/res/anim/move.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-
-   <translate
-        android:fromXDelta="0%p"
-        android:toXDelta="35%p"
-        android:duration="800" />
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="false">

+

+   <translate

+        android:fromXDelta="0%p"

+        android:toXDelta="35%p"

+        android:duration="800" />

 </set>
\ No newline at end of file
diff --git a/res/anim/move_right_leftside.xml b/res/anim/move_right_leftside.xml
index 1fd0e68..cd4423c 100644
--- a/res/anim/move_right_leftside.xml
+++ b/res/anim/move_right_leftside.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-    <translate
-        android:duration="800"
-        android:fromXDelta="0%p"
-        android:toXDelta="-12%p" >
-    </translate>
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="false">

+    <translate

+        android:duration="800"

+        android:fromXDelta="0%p"

+        android:toXDelta="-13%p" >

+    </translate>

 </set>
\ No newline at end of file
diff --git a/res/anim/move_right_rightside.xml b/res/anim/move_right_rightside.xml
index 8686ff9..b992de7 100644
--- a/res/anim/move_right_rightside.xml
+++ b/res/anim/move_right_rightside.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-    <translate
-        android:duration="800"
-        android:fromXDelta="0%p"
-        android:toXDelta="12%p" >
-    </translate>
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="false">

+    <translate

+        android:duration="800"

+        android:fromXDelta="0%p"

+        android:toXDelta="13%p" >

+    </translate>

 </set>
\ No newline at end of file
diff --git a/res/anim/slide_in_left.xml b/res/anim/slide_in_left.xml
index 249a201..a5c1dca 100644
--- a/res/anim/slide_in_left.xml
+++ b/res/anim/slide_in_left.xml
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:fillAfter="false">
-    <translate
-        android:duration="800"
-        android:fromXDelta="0%p"
-        android:toXDelta="-35%p" >
-    </translate>
+<?xml version="1.0" encoding="utf-8"?>

+<set

+    xmlns:android="http://schemas.android.com/apk/res/android"

+    android:interpolator="@android:anim/linear_interpolator"

+    android:fillAfter="false">

+    <translate

+        android:duration="800"

+        android:fromXDelta="0%p"

+        android:toXDelta="-35%p" >

+    </translate>

 </set>
\ No newline at end of file
diff --git a/res/anim/slide_in_right.xml b/res/anim/slide_in_right.xml
index c01693f..c2c8ec2 100644
--- a/res/anim/slide_in_right.xml
+++ b/res/anim/slide_in_right.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <translate
-        android:duration="600"
-        android:fromXDelta="-100%"
-        android:toXDelta="0%" >
-    </translate>
+<?xml version="1.0" encoding="utf-8"?>

+<set xmlns:android="http://schemas.android.com/apk/res/android" >

+    <translate

+        android:duration="600"

+        android:fromXDelta="-100%"

+        android:toXDelta="0%" >

+    </translate>

 </set>
\ No newline at end of file
diff --git a/res/drawable/lock_open_gray.png b/res/drawable/lock_open_gray.png
index 3c9cab4..ec4cc3d 100644
--- a/res/drawable/lock_open_gray.png
+++ b/res/drawable/lock_open_gray.png
Binary files differ
diff --git a/res/drawable/lock_sky.png b/res/drawable/lock_sky.png
index 0b3efdb..c515329 100644
--- a/res/drawable/lock_sky.png
+++ b/res/drawable/lock_sky.png
Binary files differ
diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml
index 93c61e5..fcfd723 100644
--- a/res/layout/activity_main.xml
+++ b/res/layout/activity_main.xml
@@ -1,10 +1,10 @@
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
-                android:background="#FFFFFF" >
+                android:background="#000000" >
 
   <View
-      android:id="@+id/linearroot"
+      android:id="@+id/linearroot1"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:layout_centerInParent="true"
@@ -16,7 +16,7 @@
   </View>
 
   <LinearLayout
-      android:id="@+id/linearroot"
+      android:id="@+id/linearroot2"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:layout_centerInParent="true"
@@ -50,27 +50,14 @@
 
         <ImageView
             android:id="@+id/leftside_first_left_dwar_detach"
-            android:layout_width="60dp"
+            android:layout_width="65dp"
             android:layout_height="fill_parent"
             android:layout_alignParentRight="true"
             android:layout_gravity="center"
-            android:adjustViewBounds="true"
             android:background="@drawable/leftdrawer_layer1x2"
             android:padding="19dp"
+            android:scaleType="center"
             android:src="@drawable/lock_sky" />
-
-        <ImageView
-            android:id="@+id/leftside_first_left_dwar_attach"
-            android:layout_width="60dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentLeft="false"
-            android:layout_gravity="center"
-            android:adjustViewBounds="true"
-            android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"
-            android:src="@drawable/lock_open_gray"
-            android:visibility="gone"
-            />
       </RelativeLayout>
 
       <ImageView
@@ -87,7 +74,7 @@
 
         <ImageView
             android:id="@+id/leftside_2nd_left_dwar_detach"
-            android:layout_width="60dp"
+            android:layout_width="65dp"
             android:layout_height="fill_parent"
             android:layout_alignParentRight="true"
             android:layout_gravity="center"
@@ -95,18 +82,6 @@
             android:background="@drawable/leftdrawer_layer1x2"
             android:padding="18dp"
             android:src="@drawable/lock_sky" />
-
-        <ImageView
-            android:id="@+id/leftside_2nd_left_dwar_attach"
-            android:layout_width="60dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentLeft="false"
-            android:layout_gravity="center"
-            android:adjustViewBounds="true"
-            android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"
-            android:src="@drawable/lock_open_gray"
-            android:visibility="gone" />
       </RelativeLayout>
 
       <View
@@ -117,60 +92,17 @@
       <RelativeLayout
           android:layout_width="fill_parent"
           android:layout_height="0dp"
-          android:layout_weight="0.42" >
+          android:layout_weight="0.89" >
 
         <ImageView
             android:id="@+id/leftside_3rd_left_dwar_detach"
-            android:layout_width="60dp"
+            android:layout_width="65dp"
             android:layout_height="fill_parent"
             android:layout_alignParentRight="true"
             android:layout_gravity="center"
             android:adjustViewBounds="true"
             android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"/>
-
-        <ImageView
-            android:id="@+id/leftside_3rd_left_dwar_attach"
-            android:layout_width="60dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentLeft="false"
-            android:layout_gravity="center"
-            android:adjustViewBounds="true"
-            android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"
-            android:visibility="gone" />
-      </RelativeLayout>
-
-      <View
-          android:layout_width="fill_parent"
-          android:layout_height="0dp"
-          android:layout_weight="0.07" />
-
-      <RelativeLayout
-          android:layout_width="fill_parent"
-          android:layout_height="0dp"
-          android:layout_weight="0.42" >
-
-        <ImageView
-            android:id="@+id/leftside_4th_left_dwar_detach"
-            android:layout_width="60dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentRight="true"
-            android:layout_gravity="center"
-            android:adjustViewBounds="true"
-            android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"/>
-
-        <ImageView
-            android:id="@+id/leftside_4th_left_dwar_attach"
-            android:layout_width="60dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentLeft="false"
-            android:layout_gravity="center"
-            android:adjustViewBounds="true"
-            android:background="@drawable/leftdrawer_layer1x2"
-            android:padding="18dp"
-            android:visibility="gone" />
+            android:padding="18dp" />
       </RelativeLayout>
 
       <View
@@ -206,7 +138,7 @@
 
         <ImageView
             android:id="@+id/rightside_1st_left_dwar_detach"
-            android:layout_width="120dp"
+            android:layout_width="140dp"
             android:layout_height="fill_parent"
             android:layout_alignParentLeft="true"
             android:layout_gravity="center"
@@ -215,20 +147,6 @@
             android:paddingBottom="18dp"
             android:paddingTop="18dp"
             android:src="@drawable/lock_sky" />
-
-        <ImageView
-            android:id="@+id/rightside_1st_left_dwar_attach"
-            android:layout_width="120dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentRight="true"
-            android:layout_gravity="center"
-            android:layout_marginRight="7dp"
-            android:adjustViewBounds="true"
-            android:background="@drawable/rightdrawer_layer"
-            android:paddingBottom="18dp"
-            android:paddingTop="18dp"
-            android:src="@drawable/lock_open_gray"
-            android:visibility="gone" />
       </RelativeLayout>
 
       <View
@@ -244,7 +162,7 @@
 
         <ImageView
             android:id="@+id/rightside_2nd_left_dwar_detach"
-            android:layout_width="120dp"
+            android:layout_width="140dp"
             android:layout_height="fill_parent"
             android:layout_alignParentLeft="true"
             android:layout_gravity="center"
@@ -252,19 +170,6 @@
             android:background="@drawable/rightdrawer_layer_big"
             android:padding="45dp"
             android:src="@drawable/lock_sky" />
-
-        <ImageView
-            android:id="@+id/rightside_2nd_left_dwar_attach"
-            android:layout_width="120dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentRight="true"
-            android:layout_gravity="center"
-            android:layout_marginRight="7dp"
-            android:adjustViewBounds="true"
-            android:background="@drawable/rightdrawer_layer_big"
-            android:padding="45dp"
-            android:src="@drawable/lock_open_gray"
-            android:visibility="gone" />
       </RelativeLayout>
 
       <View
@@ -280,7 +185,7 @@
 
         <ImageView
             android:id="@+id/rightside_3rd_left_dwar_detach"
-            android:layout_width="120dp"
+            android:layout_width="140dp"
             android:layout_height="fill_parent"
             android:layout_alignParentLeft="true"
             android:layout_gravity="center"
@@ -288,19 +193,6 @@
             android:background="@drawable/rightdrawer_layer_big"
             android:padding="45dp"
             android:src="@drawable/lock_sky" />
-
-        <ImageView
-            android:id="@+id/rightside_3rd_left_dwar_attach"
-            android:layout_width="120dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentRight="true"
-            android:layout_gravity="center"
-            android:layout_marginRight="7dp"
-            android:adjustViewBounds="true"
-            android:background="@drawable/rightdrawer_layer_big"
-            android:padding="45dp"
-            android:src="@drawable/lock_open_gray"
-            android:visibility="gone" />
       </RelativeLayout>
 
       <View
@@ -316,25 +208,13 @@
 
         <ImageView
             android:id="@+id/rightside_4th_left_dwar_detach"
-            android:layout_width="120dp"
+            android:layout_width="140dp"
             android:layout_height="fill_parent"
             android:layout_alignParentLeft="true"
             android:layout_gravity="center"
             android:adjustViewBounds="true"
             android:background="@drawable/rightdrawer_layer"
-            android:padding="20dp"/>
-
-        <ImageView
-            android:id="@+id/rightside_4th_left_dwar_attach"
-            android:layout_width="120dp"
-            android:layout_height="fill_parent"
-            android:layout_alignParentRight="true"
-            android:layout_gravity="center"
-            android:layout_marginRight="7dp"
-            android:adjustViewBounds="true"
-            android:background="@drawable/rightdrawer_layer"
-            android:padding="20dp"
-            android:visibility="gone" />
+            android:padding="20dp" />
       </RelativeLayout>
 
       <View
diff --git a/src/com/projectara/araepm/MainActivity.java b/src/com/projectara/araepm/MainActivity.java
index cd8dfb3..c0d1cac 100644
--- a/src/com/projectara/araepm/MainActivity.java
+++ b/src/com/projectara/araepm/MainActivity.java
@@ -16,44 +16,41 @@
 
 package com.projectara.araepm;
 
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
 import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
 import android.view.animation.AnimationUtils;
+import android.view.animation.TranslateAnimation;
 import android.view.View;
 import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
+import android.widget.RelativeLayout;
 import android.widget.Switch;
 import android.widget.Toast;
 
 public class MainActivity extends Activity
-    implements AnimationListener, EpmController.EpmChangeCallback {
+    implements EpmController.EpmChangeCallback {
 
     private static final String TAG = "AraEPM";
+    private static final int LOCK_TRANSLATE_DISTANCE = 40;
 
     //
     // The following group of fields are locked by `this'.
     //
-
-    // Index into {left,right}Side{Attach,Detach}, depending on
-    // current animation (which we obtain in onAnimationEnd).
-    //
-    // If no animation ongoing, this is -1.
-    private int ivIndex;
     // If true, an EPM change is ongoing.
     private boolean epmChangeOngoing;
     // If false, button clicks will be ignored.
     private boolean buttonPressesEnabled;
 
-    private ImageView leftSideAttach[];
-    private ImageView leftSideDetach[];
-    private ImageView rightSideAttach[];
-    private ImageView rightSideDetach[];
-
-    private Animation leftsideAnimAttach,leftsideAnimDetach;
-    private Animation rightsideAnimAttach, rightsideAnimDetach;
-
     private EpmController epmController;
 
     private static String EPM_ATTACHED;
@@ -66,6 +63,130 @@
     private static String EPM_STATUS_ERROR;
     private static String EPM_STATUS_TIMEOUT;
 
+    private Module modules[];
+
+    private class Module implements View.OnClickListener, AnimatorListener {
+    	private boolean locked;
+    	private boolean isLeft;
+    	private ImageView view;
+        private int port;
+
+    	public Module(ImageView view, boolean isLeft, int port) {
+    		this.locked = true;
+    		this.view = view;
+    		this.isLeft = isLeft;
+            this.port = port;
+
+    		view.setScaleType(ScaleType.CENTER);
+            view.setImageResource(R.drawable.lock_sky);
+            view.animate().setListener(this);
+            view.setOnClickListener(this);
+    	}
+
+        public String toString() {
+            return "ModuleOnClickListener(isLeft=" + isLeft +
+                ", port=" + port+ ",locked=" + locked + ")";
+        }
+
+
+		@Override
+		public void onAnimationStart(Animator animation) {
+		}
+
+		@Override
+		public void onAnimationEnd(Animator animation) {
+            Log.d(TAG, "onAnimationEnd");
+
+            if (locked) {
+                view.setScaleType(ScaleType.CENTER);
+                view.setImageResource(R.drawable.lock_sky);
+            } else {
+                view.setImageResource(R.drawable.lock_open_gray);
+            }
+//            synchronized (this) {
+//                enableButtonPressesLocked();
+//            }
+		}
+
+		@Override
+		public void onAnimationCancel(Animator animation) {
+		}
+
+		@Override
+		public void onAnimationRepeat(Animator animation) {
+		}
+
+        // The layout, ignoring the buttons that are occupied by the
+        // switch (marked XX), looks like this, with port numbers
+        // underneath:
+        //
+        // +-----------------------+
+        // |       |     R1        |
+        // |  L1   |     4         |
+        // |  3    +---------------+
+        // |       |               |
+        // |       |               |
+        // +-------+     R2        +
+        // |       |     2         |
+        // |  L2   |               |
+        // |  1    +---------------+
+        // |       |               |
+        // |       |               |
+        // +-------+     R3        +
+        // |       |     0         |
+        // |  XX   |               |
+        // |       +---------------+
+        // |       |     XX        |
+        // |       |               |
+        // +-----------------------+
+
+        /**
+         * Handles EPM changes and mutual exclusion between buttons.
+         *
+         * Example arguments for a button listener to attach the top
+         * left EPM, when endo is viewed from rear:
+         *
+         * - isLeft=true
+         * - port=0
+         *
+         * @param isLeft Is the button on the left side of the endo,
+         *               when viewed from the rear?
+         * @param port   port number, see above
+         */
+		@Override
+		public void onClick(View v) {
+            Log.d(TAG, "onClick() handler called on: " +
+                  this.toString());
+            synchronized (MainActivity.this) {
+                if (!buttonPressesEnabled) {
+                    Log.d(TAG, "Ignoring click while EPM change is ongoing");
+                    return;
+                } else {
+                    epmChangeOngoing = true;
+                    disableButtonPressesLocked();
+                }
+            }
+
+            Log.i(TAG,
+                  (locked ? "Detaching " : "Attaching ") +
+                  " EPM on port " );
+            int distance = this.isLeft ? -LOCK_TRANSLATE_DISTANCE : LOCK_TRANSLATE_DISTANCE;
+            if (locked) {
+            	v.animate().xBy(distance);
+                epmController.detachEpm(port);
+            } else {
+            	v.animate().xBy(-distance);
+                epmController.attachEpm(port);
+            }
+
+            this.locked = !locked;
+            Log.d(TAG, "onClick() handler finished");
+
+		}
+
+    }
+
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -76,9 +197,6 @@
 
     private void enableButtonPressesLocked() {
         Log.d(TAG, "enabling button presses");
-        if (ivIndex != -1) {
-            Log.wtf(TAG, "ivIndex=" + ivIndex + ", expected -1");
-        }
         if (epmChangeOngoing) {
             Log.wtf(TAG, "epm change is still ongoing!");
         }
@@ -114,46 +232,22 @@
         epmController = null;
     }
 
-    @Override
-    public void onAnimationRepeat(Animation animation) {
-        // nop
-    }
 
-    @Override
-    public void onAnimationStart(Animation animation) {
-        // nop
-    }
-
-    @Override
-    public void onAnimationEnd(Animation animation) {
-        Log.d(TAG, "onAnimationEnd");
-
-        if (animation == leftsideAnimAttach) {
-            leftSideDetach[ivIndex].setVisibility(View.GONE);
-            leftSideAttach[ivIndex].setVisibility(View.VISIBLE);
-        }
-        if (animation == leftsideAnimDetach) {
-            leftSideAttach[ivIndex].setVisibility(View.GONE);
-            leftSideDetach[ivIndex].setVisibility(View.VISIBLE);
-        }
-        if (animation == rightsideAnimAttach) {
-            rightSideDetach[ivIndex].setVisibility(View.GONE);
-            rightSideAttach[ivIndex].setVisibility(View.VISIBLE);
-        }
-        if (animation == rightsideAnimDetach) {
-            rightSideAttach[ivIndex].setVisibility(View.GONE);
-            rightSideDetach[ivIndex].setVisibility(View.VISIBLE);
-        }
-
+    public void initializeImageviewAnimation() {
+    	modules = new Module[] {
+            new Module((ImageView)findViewById(R.id.leftside_first_left_dwar_detach), true, 3),
+            new Module((ImageView)findViewById(R.id.leftside_2nd_left_dwar_detach), true, 1),
+            new Module((ImageView)findViewById(R.id.rightside_1st_left_dwar_detach), false, 4),
+            new Module((ImageView)findViewById(R.id.rightside_2nd_left_dwar_detach), false, 2),
+            new Module((ImageView)findViewById(R.id.rightside_3rd_left_dwar_detach), false, 0),
+    	};
         synchronized (this) {
-            ivIndex = -1;
-            if (!epmChangeOngoing) {
-                enableButtonPressesLocked();
-            }
+            epmChangeOngoing = false;
+            enableButtonPressesLocked();
         }
     }
 
-    @Override
+
     public void onEpmChangeFinished(EpmController.EpmState state,
                                     EpmController.EpmChangeStatus status,
                                     int port) {
@@ -201,208 +295,8 @@
 
         synchronized (this) {
             epmChangeOngoing = false;
-            if (ivIndex == -1) {
-                enableButtonPressesLocked();
-            }
-        }
-    }
-
-    public void initializeImageviewAnimation() {
-        leftSideAttach = new ImageView[] {
-            (ImageView) findViewById(R.id.leftside_first_left_dwar_attach),
-            (ImageView) findViewById(R.id.leftside_2nd_left_dwar_attach),
-            (ImageView) findViewById(R.id.leftside_3rd_left_dwar_attach),
-            (ImageView) findViewById(R.id.leftside_4th_left_dwar_attach)};
-
-        leftSideDetach = new ImageView[] {
-            (ImageView) findViewById(R.id.leftside_first_left_dwar_detach),
-            (ImageView) findViewById(R.id.leftside_2nd_left_dwar_detach),
-            (ImageView) findViewById(R.id.leftside_3rd_left_dwar_detach),
-            (ImageView) findViewById(R.id.leftside_4th_left_dwar_detach)};
-
-        rightSideAttach = new ImageView[] {
-            (ImageView) findViewById(R.id.rightside_1st_left_dwar_attach),
-            (ImageView) findViewById(R.id.rightside_2nd_left_dwar_attach),
-            (ImageView) findViewById(R.id.rightside_3rd_left_dwar_attach),
-            (ImageView) findViewById(R.id.rightside_4th_left_dwar_attach)};
-
-        rightSideDetach = new ImageView[] {
-            (ImageView) findViewById(R.id.rightside_1st_left_dwar_detach),
-            (ImageView) findViewById(R.id.rightside_2nd_left_dwar_detach),
-            (ImageView) findViewById(R.id.rightside_3rd_left_dwar_detach),
-            (ImageView) findViewById(R.id.rightside_4th_left_dwar_detach)};
-
-        // Load animations and set listener.
-        leftsideAnimAttach = AnimationUtils.loadAnimation(getApplicationContext(),
-                                                          R.anim.leftside_move_leftside);
-        leftsideAnimDetach = AnimationUtils.loadAnimation(getApplicationContext(),
-                                                          R.anim.leftside_move_rightside);
-        rightsideAnimAttach = AnimationUtils.loadAnimation(getApplicationContext(),
-                                                           R.anim.move_right_rightside);
-        rightsideAnimDetach = AnimationUtils.loadAnimation(getApplicationContext(),
-                                                           R.anim.move_right_leftside);
-        leftsideAnimAttach.setAnimationListener(this);
-        leftsideAnimDetach.setAnimationListener(this);
-        rightsideAnimAttach.setAnimationListener(this);
-        rightsideAnimDetach.setAnimationListener(this);
-
-        // All set; initialize EPM image views and event handling.
-        for (int i = 0; i < leftSideAttach.length; i++) {
-            ImageView iv = leftSideAttach[i];
-            iv.setVisibility(View.GONE);
-            iv.setOnClickListener(new EpmButtonClickListener(iv, true, i, true));
-        }
-        for (int i = 0; i < rightSideAttach.length; i++) {
-            ImageView iv = rightSideAttach[i];
-            iv.setVisibility(View.GONE);
-            iv.setOnClickListener(new EpmButtonClickListener(iv, false, i, true));
-        }
-        for (int i = 0; i < leftSideDetach.length; i++) {
-            ImageView iv = leftSideDetach[i];
-            iv.setOnClickListener(new EpmButtonClickListener(iv, true, i, false));
-        }
-        for (int i = 0; i < rightSideDetach.length; i++) {
-            ImageView iv = rightSideDetach[i];
-            iv.setOnClickListener(new EpmButtonClickListener(iv, false, i, false));
-        }
-
-        synchronized (this) {
-            ivIndex = -1;
-            epmChangeOngoing = false;
             enableButtonPressesLocked();
         }
     }
 
-    class EpmButtonClickListener implements View.OnClickListener {
-        private ImageView iv;
-        private boolean isLeft;
-        private int index;
-        private boolean isAttach;
-
-        /**
-         * Handles EPM changes and mutual exclusion between buttons.
-         *
-         * Example arguments for a button listener to attach the top
-         * left EPM, when endo is viewed from rear:
-         *
-         * - iv=(the button)
-         * - isLeft=true
-         * - index=0
-         * - isAttach=true
-         *
-         * @param iv     The ImageView clicked.
-         * @param isLeft Is the button on the left side of the endo,
-         *               when viewed from the rear?
-         * @param index  Zero-indexed button number, from endo top
-         * @param attach Should the button, when clicked, attach the EPM?
-         */
-        public EpmButtonClickListener(ImageView iv, boolean isLeft,
-                                      int index, boolean isAttach) {
-            this.iv = iv;
-            this.isLeft = isLeft;
-            this.index = index;
-            this.isAttach = isAttach;
-        }
-
-        @Override
-        public String toString() {
-            return "EpmButtonClickListener(iv=" + iv + ", isLeft=" + isLeft +
-                ", index=" + index + ",isAttach=" + isAttach + ")";
-        }
-
-        @Override
-        public void onClick(View v) {
-            Log.d(TAG, "onClick() handler called on: " +
-                  EpmButtonClickListener.this.toString());
-            int port = getPort();
-            if (port == -1) {
-                Log.e(TAG, "onClick: invalid state");
-                return;
-            }
-
-            // Enforce a single animation per EPM change.
-            synchronized (MainActivity.this) {
-                if (!buttonPressesEnabled) {
-                    Log.d(TAG, "Ignoring click while EPM change is ongoing");
-                    return;
-                } else {
-                    ivIndex = index;
-                    epmChangeOngoing = true;
-                    disableButtonPressesLocked();
-                }
-            }
-
-            iv.clearAnimation();
-            Log.i(TAG,
-                  (isAttach ? "Attaching " : "Detaching ") +
-                  " EPM on port " + port);
-            if (isAttach) {
-                epmController.attachEpm(port);
-            } else {
-                epmController.detachEpm(port);
-            }
-            // (The animations have confusing names.)
-            if (isLeft) {
-                if (isAttach) {
-                    v.startAnimation(leftsideAnimDetach);
-                } else {
-                    v.startAnimation(leftsideAnimAttach);
-                }
-            } else {
-                if (isAttach) {
-                    v.startAnimation(rightsideAnimDetach);
-                } else {
-                    v.startAnimation(rightsideAnimAttach);
-                }
-            }
-            Log.d(TAG, "onClick() handler finished");
-        }
-
-        // The layout, ignoring the buttons that are occupied by the
-        // switch (marked XX), looks like this, with port numbers
-        // underneath:
-        //
-        // +-----------------------+
-        // |       |     R1        |
-        // |  L1   |     4         |
-        // |  3    +---------------+
-        // |       |               |
-        // |       |               |
-        // +-------+     R2        +
-        // |       |     2         |
-        // |  L2   |               |
-        // |  1    +---------------+
-        // |       |               |
-        // |       |               |
-        // +-------+     R3        +
-        // |       |     0         |
-        // |  XX   |               |
-        // |       +---------------+
-        // |       |     XX        |
-        // |       |               |
-        // +-----------------------+
-        private int getPort() {
-            if (isLeft) {
-                switch (index) {
-                case 0:
-                    return 3;
-                case 1:
-                    return 1;
-                default:
-                    return -1;
-                }
-            } else {
-                switch (index) {
-                case 0:
-                    return 4;
-                case 1:
-                    return 2;
-                case 2:
-                    return 0;
-                default:
-                    return -1;
-                }
-            }
-        }
-    }
 }