+package net.sf.openrocket.android.thrustcurve;\r
+\r
+import net.sf.openrocket.android.db.DbAdapter;\r
+import net.sf.openrocket.android.motor.ExtendedThrustCurveMotor;\r
+import android.app.Activity;\r
+import android.app.AlertDialog;\r
+import android.app.ProgressDialog;\r
+import android.content.DialogInterface;\r
+import android.os.Handler;\r
+import android.util.Log;\r
+\r
+/**\r
+ * TCQueryAction is a class which provides all the functionality required\r
+ * to download motor data from thrustcurve. It includes UI element for\r
+ * progress and error reporting dialogs.\r
+ * \r
+ * To use the class, instantiate a new instance of TCQueryAction passing in the\r
+ * owning Activity.\r
+ * \r
+ * The Activity should implement TCQueryAction.OnComplete or provide an implementation of\r
+ * TCQueryAction.OnComplete to be notified when the download process is complete.\r
+ * \r
+ * A search and download is started with TCQueryActivity.start( SearchRequest ). The TCQueryActivity\r
+ * produces and updates a progress dialog. When the process is complete, the TCQueryActivity will notify\r
+ * the registered TCQueryAction.OnComplete handler.\r
+ * \r
+ * When the parent Activity is dismissed, it must call TCQueryAction.dismiss() to free resources.\r
+ * \r
+ */\r
+public class TCQueryAction {\r
+\r
+ public interface OnComplete {\r
+ public void onComplete();\r
+ }\r
+\r
+ private final static String TAG = "TCQueryAction";\r
+\r
+ private DbAdapter mDbHelper;\r
+\r
+ private ProgressDialog progress;\r
+ private Thread downloadThread;\r
+ private Handler handler;\r
+\r
+ private final Activity parent;\r
+ private OnComplete onCompleteListener;\r
+\r
+ /**\r
+ * Create a new TCQueryAction.\r
+ * \r
+ * If the parent implements TCQueryAction.OnComplete, it will be used as the\r
+ * onCompleteListener and notified when the process is finished.\r
+ * \r
+ * @param parent\r
+ */\r
+ public TCQueryAction( Activity parent ) {\r
+ this.parent = parent;\r
+\r
+ mDbHelper = new DbAdapter(this.parent);\r
+ mDbHelper.open();\r
+\r
+ if (parent instanceof OnComplete ) {\r
+ this.onCompleteListener = (OnComplete) parent;\r
+ }\r
+ }\r
+\r
+ public void setOnCompleteListener(OnComplete onCompleteListener) {\r
+ this.onCompleteListener = onCompleteListener;\r
+ }\r
+ \r
+ public void start( SearchRequest request) {\r
+ Downloader d = new Downloader(request);\r
+\r
+ handler = new Handler();\r
+ progress = ProgressDialog.show(parent, null, "");\r
+\r
+ downloadThread = new Thread( d );\r
+ downloadThread.start();\r
+\r
+ }\r
+\r
+ public void dismiss() {\r
+ // TODO - need to kill the thread.\r
+ \r
+ mDbHelper.close();\r
+ \r
+ if ( progress.isShowing() ) {\r
+ progress.dismiss();\r
+ }\r
+ }\r
+ \r
+ private class UpdateMessage implements Runnable {\r
+ private String newMessage;\r
+ UpdateMessage( String message ) {\r
+ this.newMessage = message;\r
+ }\r
+ @Override\r
+ public void run() {\r
+ progress.setMessage(newMessage);\r
+ }\r
+ }\r
+\r
+ private class Dismiss implements Runnable {\r
+ @Override\r
+ public void run() {\r
+ progress.dismiss();\r
+ if (onCompleteListener != null ) {\r
+ onCompleteListener.onComplete();\r
+ }\r
+ // TCQueryActivity.this.finish();\r
+ }\r
+ }\r
+\r
+ private class Error implements Runnable {\r
+ private String newMessage;\r
+ Error( String message ) {\r
+ this.newMessage = message;\r
+ }\r
+ @Override\r
+ public void run() {\r
+ progress.dismiss();\r
+ final AlertDialog dialog = new AlertDialog.Builder(parent).create();\r
+ dialog.setMessage(newMessage);\r
+ dialog.setButton(DialogInterface.BUTTON_NEUTRAL,"Dismiss", new DialogInterface.OnClickListener() {\r
+\r
+ @Override\r
+ public void onClick(DialogInterface arg0, int arg1) {\r
+ dialog.dismiss();\r
+ }\r
+\r
+ });\r
+ dialog.show();\r
+ }\r
+ }\r
+\r
+ private class Downloader implements Runnable {\r
+\r
+ SearchRequest request;\r
+\r
+ Downloader( SearchRequest request ) {\r
+ this.request = request;\r
+ }\r
+\r
+ @Override\r
+ public void run() {\r
+ try {\r
+ handler.post( new UpdateMessage("Quering Thrustcurve"));\r
+ SearchResponse res = new ThrustCurveAPI().doSearch(request);\r
+\r
+ int total = res.getResults().size();\r
+ int count = 1;\r
+ for( TCMotor mi : res.getResults() ) {\r
+ handler.post(new UpdateMessage("Downloading details " + count + " of " + total));\r
+ count++;\r
+ if ( mi.getData_files() == null || mi.getData_files().intValue() == 0 ) {\r
+ continue;\r
+ }\r
+\r
+ MotorBurnFile b = new ThrustCurveAPI().downloadData(mi.getMotor_id());\r
+\r
+ Log.d(TAG, mi.toString());\r
+\r
+ ExtendedThrustCurveMotor m = new ExtendedThrustCurveMotor();\r
+\r
+ m.setThrustCurveMotor( b.getThrustCurveMotor() );\r
+\r
+ // Convert impulse class. ThrustCurve puts mmx, 1/4a and 1/2a as A.\r
+ m.setImpulseClass(mi.getImpulse_class());\r
+ if ( "a".equalsIgnoreCase(mi.getImpulse_class())) {\r
+ if( mi.getCommon_name().startsWith("1/2A") ) {\r
+ m.setImpulseClass("1/2A");\r
+ } else if (mi.getCommon_name().startsWith("1/4A") ) {\r
+ m.setImpulseClass("1/4A");\r
+ } else if (mi.getCommon_name().startsWith("Micro") ) {\r
+ m.setImpulseClass("1/8A");\r
+ }\r
+ }\r
+\r
+ // Convert Case Info.\r
+ if ( mi.getCase_info() == null\r
+ || "single use".equalsIgnoreCase(mi.getCase_info())\r
+ || "single-use".equalsIgnoreCase(mi.getCase_info())) {\r
+ m.setCaseInfo(mi.getType()+ " " + mi.getDiameter() + "x" + mi.getLength());\r
+ } else {\r
+ m.setCaseInfo(mi.getCase_info());\r
+ }\r
+\r
+ Log.d(TAG,"adding motor " + m.toString());\r
+ // Write motor.\r
+ mDbHelper.getMotorDao().insertOrUpdateMotor(m);\r
+ }\r
+ if ( total < res.getMatches() ) {\r
+ handler.post( new Error( total + " motors downloaded, " + res.getMatches() + " matched. Try restricting the query more.") );\r
+ } else {\r
+ handler.post( new Dismiss());\r
+ }\r
+ }\r
+ catch( Exception ex){\r
+ Log.d(TAG,ex.toString());\r
+ handler.post( new Error(ex.toString()) );\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+}\r