/* @file GMActivity.java
*
* @author marco corvi
* @date may 2012
*
* @brief TopoDroid calibration data activity
* --------------------------------------------------------
* Copyright This sowftare is distributed under GPL-3.0 or later
* See the file COPYING.
* --------------------------------------------------------
*/
package com.topodroid.DistoX;
// import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
// import java.lang.Long;
// import java.lang.reflect.Method;
// import java.lang.reflect.InvocationTargetException;
import android.app.Application;
import android.app.Activity;
// import android.content.res.ColorStateList;
import android.os.Bundle;
import android.os.AsyncTask;
// import android.os.Handler;
// import android.os.Message;
// import android.os.Parcelable;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.DialogInterface;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.ListView;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.KeyEvent;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.view.Menu;
import android.view.MenuItem;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
public class GMActivity extends Activity
implements OnItemClickListener
, ILister
, IEnableButtons
, OnClickListener
{
private TopoDroidApp mApp;
private CalibAlgo mCalibration = null;
private String mSaveData; // saved GM text representation
private TextView mSaveTextView; // view of the saved GM
private CalibCBlock mSaveCBlock = null; // data of the saved GM
private long mCIDid = -1; // id of the GM
private int mBlkStatus = 0; // min display Group (can be either 1 [only active] or 0 [all])
private int mAlgo; // calibration algorithm
private ListView mList; // display list
private MenuItem mMIoptions;
private MenuItem mMIdisplay;
private MenuItem mMIhelp;
private CalibCBlockAdapter mDataAdapter; // adapter for the list of GM's
private String mCalibName;
// private ConnHandler mHandler;
private static int izons[] = {
R.drawable.iz_download,
R.drawable.iz_toggle,
R.drawable.iz_numbers_no,
R.drawable.iz_compute,
R.drawable.iz_cover,
R.drawable.iz_read,
R.drawable.iz_write
};
final static int BTN_DOWNLOAD = 0;
final static int BTN_TOGGLE = 1;
final static int BTN_COVER = 4;
final static int BTN_READ = 5;
final static int BTN_WRITE = 6;
static int izonsno[] = {
R.drawable.iz_download_on,
R.drawable.iz_toggle_no,
0,
0,
R.drawable.iz_cover_no,
R.drawable.iz_read_no,
R.drawable.iz_write_no
};
static int menus[] = {
R.string.menu_display,
R.string.menu_validate,
R.string.menu_options,
R.string.menu_help
};
static int help_icons[] = {
R.string.help_download,
R.string.help_toggle,
R.string.help_group,
R.string.help_compute,
R.string.help_cover,
R.string.help_read,
R.string.help_write
};
static int help_menus[] = {
R.string.help_display_calib,
R.string.help_validate,
R.string.help_prefs,
R.string.help_help
};
final static int mNrButton1 = 7;
private Button[] mButton1;
HorizontalListView mListView;
HorizontalButtonView mButtonView1;
boolean mEnableWrite;
ListView mMenu;
Button mImage;
// HOVER
// MyMenuAdapter mMenuAdapter;
ArrayAdapter< String > mMenuAdapter;
boolean onMenu;
BitmapDrawable mBMtoggle;
BitmapDrawable mBMtoggle_no;
BitmapDrawable mBMcover;
BitmapDrawable mBMcover_no;
BitmapDrawable mBMread;
BitmapDrawable mBMread_no;
BitmapDrawable mBMwrite;
BitmapDrawable mBMwrite_no;
BitmapDrawable mBMdownload;
BitmapDrawable mBMdownload_on;
public void setTheTitle() { }
// -------------------------------------------------------------------
// forward survey name to DeviceHelper
// -------------------------------------------------------------
/** called by CalibComputer Task
* @return nr of iterations (neg. error)
* @note run on an AsyncTask
*/
int computeCalib()
{
long cid = mApp.mCID;
if ( cid < 0 ) return -2;
List<CalibCBlock> list = mApp.mDData.selectAllGMs( cid, 0 );
if ( list.size() < 16 ) {
return -1;
}
int ng = 0; // cb with group
for ( CalibCBlock cb : list ) {
if ( cb.mGroup > 0 ) ++ng;
}
if ( ng < 16 ) {
return -3;
}
switch ( mAlgo ) {
case CalibInfo.ALGO_NON_LINEAR:
mCalibration = new CalibAlgoBH( 0, true );
// FIXME set the calibration algorithm (whether non-linear or linear)
// mCalibration.setAlgorith( mAlgo == 2 ); // CALIB_AUTO_NON_LINEAR
break;
case CalibInfo.ALGO_MINIMUM:
if ( TDSetting.mLevelOverExperimental ) {
mCalibration = new CalibAlgoMin( 0, false );
break;
}
default: // linear algo
mCalibration = new CalibAlgoBH( 0, false );
}
mCalibration.Reset( list.size() );
for ( CalibCBlock item : list ) mCalibration.AddValues( item );
int iter = mCalibration.Calibrate();
if ( iter > 0 ) {
float[] errors = mCalibration.Errors();
for ( int k = 0; k < list.size(); ++k ) {
CalibCBlock cb = list.get( k );
mApp.mDData.updateGMError( cb.mId, cid, errors[k] );
// cb.setError( errors[k] );
}
byte[] coeff = mCalibration.GetCoeff();
mApp.mDData.updateCalibCoeff( cid, CalibAlgo.coeffToString( coeff ) );
mApp.mDData.updateCalibError( cid,
mCalibration.Delta(),
mCalibration.Delta2(),
mCalibration.MaxError(),
iter );
// DEBUG:
// Calibration.logCoeff( coeff );
// coeff = Calibration.stringToCoeff( mApp.mDData.selectCalibCoeff( cid ) );
// Calibration.logCoeff( coeff );
}
// Log.v( TopoDroidApp.TAG, "iteration " + iter );
return iter;
}
/** validate this calibration against another calibration
*/
void validateCalibration( String name )
{
String device = mApp.distoAddress();
if ( device == null ) return;
Long cid = mApp.mDData.getCalibCID( name, device );
if ( cid < 0 ) {
return;
}
List<CalibCBlock> list = mApp.mDData.selectAllGMs( mApp.mCID, 0 );
List<CalibCBlock> list1 = mApp.mDData.selectAllGMs( cid, 0 );
// list.addAll( list1 );
int size = list.size();
int size1 = list1.size();
if ( size < 16 || size1 < 16 ) {
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
return;
}
String coeffStr = mApp.mDData.selectCalibCoeff( cid );
int algo = mApp.mDData.selectCalibAlgo( cid );
if ( algo == 0 ) algo = mApp.getCalibAlgoFromDevice();
CalibAlgo calib1 = null;
switch ( algo ) {
case CalibInfo.ALGO_NON_LINEAR:
calib1 = new CalibAlgoBH( CalibAlgo.stringToCoeff( coeffStr ), true );
break;
case CalibInfo.ALGO_MINIMUM:
if ( TDSetting.mLevelOverExperimental ) {
calib1 = new CalibAlgoMin( CalibAlgo.stringToCoeff( coeffStr ), false );
break;
}
default:
calib1 = new CalibAlgoBH( CalibAlgo.stringToCoeff( coeffStr ), false );
}
// Log.v("DistoX", "Calib-1 algo " + algo );
// calib1.dump();
coeffStr = mApp.mDData.selectCalibCoeff( mApp.mCID );
algo = mApp.mDData.selectCalibAlgo( mApp.mCID );
if ( algo == 0 ) algo = mApp.getCalibAlgoFromDevice();
CalibAlgo calib0 = null;
switch ( algo ) {
case CalibInfo.ALGO_NON_LINEAR:
calib0 = new CalibAlgoBH( CalibAlgo.stringToCoeff( coeffStr ), true );
break;
case CalibInfo.ALGO_MINIMUM:
if ( TDSetting.mLevelOverExperimental ) {
calib0 = new CalibAlgoMin( CalibAlgo.stringToCoeff( coeffStr ), false );
break;
}
default:
calib0 = new CalibAlgoBH( CalibAlgo.stringToCoeff( coeffStr ), false );
}
// Log.v("DistoX", "Calib-0 algo " + algo );
// calib0.dump();
float[] errors0 = new float[ list.size() ];
float[] errors1 = new float[ list1.size() ];
int ke1 = computeErrorStats( calib0, list1, errors1 );
int ke0 = computeErrorStats( calib1, list, errors0 );
double ave0 = calib0.getStatError() / calib0.getStatCount();
double std0 = Math.sqrt( calib0.getStatError2() / calib0.getStatCount() - ave0 * ave0 + 1e-8 );
double ave1 = calib1.getStatError() / calib1.getStatCount();
double std1 = Math.sqrt( calib1.getStatError2() / calib1.getStatCount() - ave1 * ave1 + 1e-8 );
ave0 *= TDMath.RAD2GRAD;
std0 *= TDMath.RAD2GRAD;
ave1 *= TDMath.RAD2GRAD;
std1 *= TDMath.RAD2GRAD;
list.addAll( list1 );
size = list.size();
float[] errors = new float[ size ];
double err1 = 0; // average error [radians]
double err2 = 0;
double errmax = 0;
int ke = 0;
for ( CalibCBlock b : list ) {
Vector g = new Vector( b.gx, b.gy, b.gz );
Vector m = new Vector( b.mx, b.my, b.mz );
Vector v0 = calib0.computeDirection(g,m);
Vector v1 = calib1.computeDirection(g,m);
double err = v0.minus( v1 ).Length();
errors[ke++] = (float) err;
err1 += err;
err2 += err * err;
if ( err > errmax ) errmax = err;
}
err1 /= size;
err2 = Math.sqrt( err2/size - err1 * err1 );
err1 *= TDMath.RAD2GRAD;
err2 *= TDMath.RAD2GRAD;
errmax *= TDMath.RAD2GRAD;
new CalibValidateResultDialog( this, errors0, errors1, errors,
ave0, std0, ave1, std1, err1, err2, errmax, name, mApp.myCalib ).show();
}
/** compute the error stats of the data of this calibration using the
* coeffiecients of another calibration
* @param name the other calibration name
* @return number of errors in the array
*/
private int computeErrorStats( CalibAlgo calib, List<CalibCBlock> list, float[] errors )
{
int ke = 0; // number of errors
for ( int c=0; c<errors.length; ++c ) errors[c] = -1;
calib.initErrorStats();
long group = 0;
int k = 0;
int cnt = 0;
while( k < list.size() && list.get(k).mGroup <= 0 ) ++k;
for ( int j=k; j<list.size(); ++j ) {
if ( list.get(j).mGroup > 0 ) {
if ( list.get(j).mGroup != group ) {
if ( cnt > 0 ) {
Vector g[] = new Vector[cnt];
Vector m[] = new Vector[cnt];
float e[] = new float[cnt];
int i=0;
for ( ; k<j; ++k ) {
CalibCBlock b = list.get(k);
if ( b.mGroup == group ) {
g[i] = new Vector( b.gx, b.gy, b.gz );
m[i] = new Vector( b.mx, b.my, b.mz );
e[i] = -1;
++i;
}
}
calib.addStatErrors( g, m, e );
for ( int c=0; c<cnt; ++c ) errors[ ke++ ] = e[c];
}
group = list.get(j).mGroup;
cnt = 1;
} else {
cnt ++;
}
}
}
if ( cnt > 0 ) {
Vector g[] = new Vector[cnt];
Vector m[] = new Vector[cnt];
float e[] = new float[cnt];
int i=0;
for ( ; k<list.size(); ++k ) {
CalibCBlock b = list.get(k);
if ( b.mGroup == group ) {
g[i] = new Vector( b.gx, b.gy, b.gz );
m[i] = new Vector( b.mx, b.my, b.mz );
e[i] = -1;
++i;
}
}
calib.addStatErrors( g, m, e );
for ( int c=0; c<cnt; ++c ) errors[ ke++ ] = e[c];
}
return ke;
}
void handleComputeCalibResult( int job, int result )
{
switch ( job ) {
case CalibComputer.CALIB_COMPUTE_CALIB:
resetTitle( );
// Log.v("DistoX", "compute result " + result );
if ( result > 0 ) {
enableWrite( true );
Vector bg = mCalibration.GetBG();
Matrix ag = mCalibration.GetAG();
Vector bm = mCalibration.GetBM();
Matrix am = mCalibration.GetAM();
Vector nL = mCalibration.GetNL();
byte[] coeff = mCalibration.GetCoeff();
float[] errors = mCalibration.Errors();
(new CalibCoeffDialog( this, mApp, bg, ag, bm, am, nL, errors,
mCalibration.Delta(), mCalibration.Delta2(), mCalibration.MaxError(),
result, coeff ) ).show();
} else if ( result == 0 ) {
Toast.makeText( this, R.string.few_iter, Toast.LENGTH_SHORT ).show();
return;
} else if ( result == -1 ) {
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
return;
} else if ( result == -2 ) {
return;
} else if ( result == -3 ) {
Toast.makeText( this, R.string.few_groups, Toast.LENGTH_SHORT ).show();
return;
} else {
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
return;
}
break;
case CalibComputer.CALIB_RESET_GROUPS:
break;
case CalibComputer.CALIB_COMPUTE_GROUPS:
case CalibComputer.CALIB_RESET_AND_COMPUTE_GROUPS:
if ( result < 0 ) {
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
} else {
Toast.makeText( this, "Found " + result + " groups", Toast.LENGTH_SHORT ).show();
}
break;
default:
}
updateDisplay( );
}
/** called by CalibComputer Task
* @param start_id id of the GM-data to start with
* @note run on an AsyncTask
*/
void doResetGroups( long start_id )
{
// Log.v("DistoX", "Reset CID " + mApp.mCID + " from gid " + start_id );
mApp.mDData.resetAllGMs( mApp.mCID, start_id ); // reset all groups where status=0, and id >= start_id
}
/** called by CalibComputer Task
* @note run on an AsyncTask
*/
int doComputeGroups( long start_id )
{
long cid = mApp.mCID;
// Log.v("DistoX", "Compute CID " + cid + " from gid " + start_id );
if ( cid < 0 ) return -2;
float thr = TDMath.cosd( TDSetting.mGroupDistance );
List<CalibCBlock> list = mApp.mDData.selectAllGMs( cid, 0 );
if ( list.size() < 4 ) {
return -1;
}
long group = 0;
int cnt = 0;
float b = 0.0f;
float c = 0.0f;
if ( start_id >= 0 ) {
for ( CalibCBlock item : list ) {
if ( item.mId == start_id ) {
group = item.mGroup;
cnt = 1;
b = item.mBearing;
c = item.mClino;
break;
}
}
} else {
if ( TDSetting.mGroupBy != TDSetting.GROUP_BY_DISTANCE ) {
group = 1;
}
}
switch ( TDSetting.mGroupBy ) {
case TDSetting.GROUP_BY_DISTANCE:
for ( CalibCBlock item : list ) {
if ( start_id >= 0 && item.mId <= start_id ) continue;
if ( group == 0 || item.isFarFrom( b, c, thr ) ) {
++ group;
b = item.mBearing;
c = item.mClino;
}
item.setGroup( group );
mApp.mDData.updateGMName( item.mId, item.mCalibId, Long.toString( item.mGroup ) );
// N.B. item.calibId == cid
}
break;
case TDSetting.GROUP_BY_FOUR:
// TDLog.Log( TDLog.LOG_CALIB, "group by four");
for ( CalibCBlock item : list ) {
if ( start_id >= 0 && item.mId <= start_id ) continue;
item.setGroupIfNonZero( group );
mApp.mDData.updateGMName( item.mId, item.mCalibId, Long.toString( item.mGroup ) );
++ cnt;
if ( (cnt%4) == 0 ) {
++group;
// TDLog.Log( TDLog.LOG_CALIB, "cnt " + cnt + " new group " + group );
}
}
break;
case TDSetting.GROUP_BY_ONLY_16:
for ( CalibCBlock item : list ) {
if ( start_id >= 0 && item.mId <= start_id ) continue;
item.setGroupIfNonZero( group );
mApp.mDData.updateGMName( item.mId, item.mCalibId, Long.toString( item.mGroup ) );
++ cnt;
if ( (cnt%4) == 0 || cnt >= 16 ) ++group;
}
break;
}
return (int)group-1;
}
// -----------------------------------------------------------
// ILister interface
@Override
public void refreshDisplay( int nr, boolean toast )
{
// Log.v( TopoDroidApp.TAG, "refreshDisplay nr " + nr );
resetTitle( );
if ( nr >= 0 ) {
if ( nr > 0 ) updateDisplay( );
if ( toast ) {
Toast.makeText( this,
getResources().getQuantityString(R.plurals.read_calib_data, nr/2, nr/2, nr ),
Toast.LENGTH_SHORT ).show();
}
} else if ( nr < 0 ) {
if ( toast ) {
// Toast.makeText( this, getString(R.string.read_fail_with_code) + nr, Toast.LENGTH_SHORT ).show();
Toast.makeText( this, mApp.DistoXConnectionError[ -nr ], Toast.LENGTH_SHORT ).show();
}
}
mButton1[BTN_DOWNLOAD].setBackgroundDrawable( mBMdownload );
}
@Override
public void updateBlockList( DistoXDBlock blk ) { }
@Override
public void updateBlockList( long blk_id ) { }
@Override
public void setRefAzimuth( float azimuth, long fixed_extend ) { }
@Override
public void setConnectionStatus( int status )
{
/* nothing : GM data are downloaded only on-demand */
}
// --------------------------------------------------------------
public void updateDisplay( )
{
// Log.v( TopoDroidApp.TAG, "update Display CID " + mApp.mCID );
resetTitle( );
mDataAdapter.clear();
if ( mApp.mDData != null && mApp.mCID >= 0 ) {
List<CalibCBlock> list = mApp.mDData.selectAllGMs( mApp.mCID, mBlkStatus );
// Log.v( TopoDroidApp.TAG, "update Display GMs " + list.size() );
updateGMList( list );
setTitle( mCalibName );
}
}
private void updateGMList( List<CalibCBlock> list )
{
int n_saturated = 0;
if ( list.size() == 0 ) {
Toast.makeText( this, R.string.no_gms, Toast.LENGTH_SHORT ).show();
return;
}
for ( CalibCBlock item : list ) {
if ( item.isSaturated() ) ++ n_saturated;
mDataAdapter.add( item );
}
// mList.setAdapter( mDataAdapter );
if ( n_saturated > 0 ) {
Toast toast = Toast.makeText( this,
getResources().getQuantityString( R.plurals.calib_saturated_values, n_saturated, n_saturated), Toast.LENGTH_LONG );
toast.getView().setBackgroundColor( 0xff993333 );
toast.show();
}
}
// ---------------------------------------------------------------
// list items click
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id)
{
if ( mMenu == (ListView)parent ) {
handleMenu( pos );
return;
}
if ( onMenu ) {
closeMenu();
return;
}
CharSequence item = ((TextView) view).getText();
String value = item.toString();
// TDLog.Log( TDLog.LOG_INPUT, "GMActivity onItemClick() " + item.toString() );
// if ( value.equals( getResources().getString( R.string.back_to_calib ) ) ) {
// setStatus( STATUS_CALIB );
// updateDisplay( );
// return;
// }
mSaveCBlock = mDataAdapter.get( pos );
mSaveTextView = (TextView) view;
String msg = mSaveTextView.getText().toString();
String[] st = msg.split( " ", 3 );
try {
mCIDid = Long.parseLong(st[0]);
// String name = st[1];
mSaveData = st[2];
if ( mSaveCBlock.mStatus == 0 ) {
// startGMDialog( mCIDid, st[1] );
(new CalibGMDialog( this, this, mSaveCBlock )).show();
} else { // FIXME TODO ask whether to undelete
TopoDroidAlertDialog.makeAlert( this, getResources(), R.string.calib_gm_undelete,
new DialogInterface.OnClickListener() {
@Override
public void onClick( DialogInterface dialog, int btn ) {
// TDLog.Log( TDLog.LOG_INPUT, "calib delite" );
deleteGM( false );
}
}
);
}
} catch ( NumberFormatException e ) {
TDLog.Error( "error: expected a long, got: " + st[0] );
}
}
// ---------------------------------------------------------------
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate( savedInstanceState );
setContentView(R.layout.gm_activity);
mApp = (TopoDroidApp) getApplication();
mDataAdapter = new CalibCBlockAdapter( this, R.layout.row, new ArrayList<CalibCBlock>() );
mList = (ListView) findViewById(R.id.list);
mList.setAdapter( mDataAdapter );
mList.setOnItemClickListener( this );
mList.setDividerHeight( 2 );
// mHandler = new ConnHandler( mApp, this );
mListView = (HorizontalListView) findViewById(R.id.listview);
int size = mApp.setListViewHeight( mListView );
Resources res = getResources();
mButton1 = new Button[ mNrButton1 ];
for ( int k=0; k<mNrButton1; ++k ) {
mButton1[k] = MyButton.getButton( this, this, izons[k] );
if ( k == BTN_DOWNLOAD ) { mBMdownload = MyButton.getButtonBackground( mApp, res, izons[k] ); }
else if ( k == BTN_TOGGLE ) { mBMtoggle = MyButton.getButtonBackground( mApp, res, izons[k] ); }
else if ( k == BTN_COVER ) { mBMcover = MyButton.getButtonBackground( mApp, res, izons[k] ); }
else if ( k == BTN_READ ) { mBMread = MyButton.getButtonBackground( mApp, res, izons[k] ); }
else if ( k == BTN_WRITE ) { mBMwrite = MyButton.getButtonBackground( mApp, res, izons[k] ); }
}
mBMdownload_on = MyButton.getButtonBackground( mApp, res, izonsno[BTN_DOWNLOAD] );
mBMtoggle_no = MyButton.getButtonBackground( mApp, res, izonsno[BTN_TOGGLE] );
mBMcover_no = MyButton.getButtonBackground( mApp, res, izonsno[BTN_COVER] );
mBMread_no = MyButton.getButtonBackground( mApp, res, izonsno[BTN_READ] );
mBMwrite_no = MyButton.getButtonBackground( mApp, res, izonsno[BTN_WRITE] );
enableWrite( false );
mButtonView1 = new HorizontalButtonView( mButton1 );
mListView.setAdapter( mButtonView1.mAdapter );
mCalibName = mApp.myCalib;
mAlgo = mApp.getCalibAlgoFromDB();
// updateDisplay( );
mImage = (Button) findViewById( R.id.handle );
mImage.setOnClickListener( this );
mImage.setBackgroundDrawable( MyButton.getButtonBackground( mApp, res, R.drawable.iz_menu ) );
mMenu = (ListView) findViewById( R.id.menu );
setMenuAdapter( res );
closeMenu();
// HOVER
mMenu.setOnItemClickListener( this );
}
private void resetTitle()
{
setTitle( mCalibName );
if ( mBlkStatus == 0 ) {
setTitleColor( TDConst.COLOR_NORMAL );
} else {
setTitleColor( TDConst.COLOR_NORMAL2 );
}
}
private void enableWrite( boolean enable )
{
mEnableWrite = enable;
mButton1[BTN_COVER].setEnabled( enable );
mButton1[BTN_WRITE].setEnabled( enable );
if ( enable ) {
mButton1[BTN_COVER].setBackgroundDrawable( mBMcover );
mButton1[BTN_WRITE].setBackgroundDrawable( mBMwrite );
} else {
mButton1[BTN_COVER].setBackgroundDrawable( mBMcover_no );
mButton1[BTN_WRITE].setBackgroundDrawable( mBMwrite_no );
}
}
@Override
public void enableButtons( boolean enable )
{
mButton1[BTN_TOGGLE].setEnabled( enable );
mButton1[BTN_READ].setEnabled( enable );
mButton1[BTN_WRITE].setEnabled( enable && mEnableWrite );
mButton1[BTN_COVER].setEnabled( enable && mEnableWrite );
if ( enable ) {
setTitleColor( TDConst.COLOR_NORMAL );
mButton1[BTN_TOGGLE].setBackgroundDrawable( mBMtoggle );
mButton1[BTN_READ].setBackgroundDrawable( mBMread );
} else {
setTitleColor( TDConst.COLOR_CONNECTED );
mButton1[BTN_TOGGLE].setBackgroundDrawable( mBMtoggle_no );
mButton1[BTN_READ].setBackgroundDrawable( mBMread_no );
}
if ( enable && mEnableWrite ) {
mButton1[BTN_COVER].setBackgroundDrawable( mBMcover );
mButton1[BTN_WRITE].setBackgroundDrawable( mBMwrite );
} else {
mButton1[BTN_COVER].setBackgroundDrawable( mBMcover_no );
mButton1[BTN_WRITE].setBackgroundDrawable( mBMwrite_no );
}
}
public void onClick(View view)
{
if ( onMenu ) {
closeMenu();
return;
}
Button b = (Button)view;
if ( b == mImage ) {
if ( mMenu.getVisibility() == View.VISIBLE ) {
mMenu.setVisibility( View.GONE );
onMenu = false;
} else {
mMenu.setVisibility( View.VISIBLE );
onMenu = true;
}
return;
}
if ( b == mButton1[BTN_DOWNLOAD] ) { // DOWNLOAD
if ( ! mApp.checkCalibrationDeviceMatch() ) {
Toast.makeText( this, R.string.calib_device_mismatch, Toast.LENGTH_LONG ).show();
} else {
enableWrite( false );
setTitleColor( TDConst.COLOR_CONNECTED );
if ( mAlgo == CalibInfo.ALGO_AUTO ) {
mAlgo = mApp.getCalibAlgoFromDevice();
if ( mAlgo < CalibInfo.ALGO_AUTO ) {
Toast.makeText( this, R.string.device_algo_failed, Toast.LENGTH_SHORT ).show();
mAlgo = CalibInfo.ALGO_LINEAR;
}
mApp.updateCalibAlgo( mAlgo );
}
ListerHandler handler = new ListerHandler( this ); // FIXME LISTER
new DataDownloadTask( mApp, handler ).execute();
// new DataDownloadTask( mApp, this ).execute();
mButton1[ BTN_DOWNLOAD ].setBackgroundDrawable( mBMdownload_on );
}
} else if ( b == mButton1[BTN_TOGGLE] ) { // TOGGLE
enableButtons( false );
new CalibToggleTask( this, this, mApp ).execute();
} else if ( b == mButton1[2] ) { // GROUP
if ( mApp.mCID >= 0 ) {
List< CalibCBlock > list = mApp.mDData.selectAllGMs( mApp.mCID, 0 );
if ( list.size() >= 16 ) {
(new GMGroupsDialog( this, this,
( TDSetting.mGroupBy == TDSetting.GROUP_BY_DISTANCE )?
getResources().getString( R.string.group_policy_distance )
: ( TDSetting.mGroupBy == TDSetting.GROUP_BY_FOUR )?
getResources().getString( R.string.group_policy_four )
: /* TDSetting.GROUP_BY_ONLY_16 */
getResources().getString( R.string.group_policy_sixteen )
)).show();
// new CalibComputer( this, -1L, CalibComputer.CALIB_COMPUTE_GROUPS ).execute();
} else {
resetTitle( );
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
}
} else {
resetTitle( );
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT ).show();
}
} else if ( b == mButton1[3] ) { // COMPUTE
if ( mApp.mCID >= 0 ) {
setTitle( R.string.calib_compute_coeffs );
setTitleColor( TDConst.COLOR_COMPUTE );
if ( mAlgo == CalibInfo.ALGO_AUTO ) {
mAlgo = ( TDSetting.mCalibAlgo != CalibInfo.ALGO_AUTO ) ? TDSetting.mCalibAlgo : CalibInfo.ALGO_LINEAR;
mApp.updateCalibAlgo( mAlgo );
}
new CalibComputer( this, -1L, CalibComputer.CALIB_COMPUTE_CALIB ).execute();
} else {
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT ).show();
}
} else if ( b == mButton1[BTN_COVER] ) { // COVER
if ( mCalibration == null ) {
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT ).show();
} else {
List< CalibCBlock > list = mApp.mDData.selectAllGMs( mApp.mCID, 0 );
if ( list.size() >= 16 ) {
( new CalibCoverageDialog( this, list, mCalibration ) ).show();
} else {
Toast.makeText( this, R.string.few_data, Toast.LENGTH_SHORT ).show();
}
}
} else if ( b == mButton1[BTN_READ] ) { // READ
enableButtons( false );
new CalibReadTask( this, this, mApp, CalibReadTask.PARENT_GM ).execute(); //
} else if ( b == mButton1[BTN_WRITE] ) { // WRITE
// if ( mEnableWrite ) {
if ( mCalibration == null ) {
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT).show();
} else {
setTitle( R.string.calib_write_coeffs );
setTitleColor( TDConst.COLOR_CONNECTED );
byte[] coeff = mCalibration.GetCoeff();
if ( coeff == null ) {
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT).show();
} else {
mApp.uploadCalibCoeff( this, coeff, true );
}
resetTitle( );
}
// }
// } else if ( b == mButton1[7] ) { // disto
// Intent deviceIntent = new Intent( Intent.ACTION_VIEW ).setClass( this, DeviceActivity.class );
// startActivity( deviceIntent );
}
}
void computeGroups( long start_id )
{
setTitle( R.string.calib_compute_groups );
setTitleColor( TDConst.COLOR_COMPUTE );
new CalibComputer( this, start_id, CalibComputer.CALIB_COMPUTE_GROUPS ).execute();
}
void resetGroups( long start_id )
{
new CalibComputer( this, start_id, CalibComputer.CALIB_RESET_GROUPS ).execute();
}
void resetAndComputeGroups( long start_id )
{
setTitle( R.string.calib_compute_groups );
setTitleColor( TDConst.COLOR_COMPUTE );
new CalibComputer( this, start_id, CalibComputer.CALIB_RESET_AND_COMPUTE_GROUPS ).execute();
}
// ------------------------------------------------------------------
// LIFECYCLE
//
// onCreate --> onStart --> onResume
// --> onSaveInstanceState --> onPause --> onStop | drawing | --> onStart --> onResume
// --> onSaveInstanceState --> onPause [ off/on ] --> onResume
// --> onPause --> onStop --> onDestroy
@Override
public void onStart()
{
super.onStart();
// setBTMenus( mApp.mBTAdapter.isEnabled() );
}
@Override
public synchronized void onResume()
{
super.onResume();
// if ( mApp.mComm != null ) { mApp.mComm.resume(); }
// Log.v( TopoDroidApp.TAG, "onResume ");
updateDisplay( );
// mApp.registerConnListener( mHandler );
mApp.mGMActivityVisible = true;
}
@Override
protected synchronized void onPause()
{
super.onPause();
mApp.mGMActivityVisible = false;
// mApp.unregisterConnListener( mHandler );
// if ( mApp.mComm != null ) { mApp.mComm.suspend(); }
}
// @Override
// public synchronized void onStop()
// {
// super.onStop();
// }
// @Override
// public synchronized void onDestroy()
// {
// super.onDestroy();
// }
// ------------------------------------------------------------------
// public int downloadDataBatch()
// {
// ArrayList<ILister> listers = new ArrayList<ILister>();
// listers.add( this );
// return mApp.downloadDataBatch( this );
// }
// public void makeNewCalib( String name, String date, String comment )
// {
// long id = setCalibFromName( name );
// if ( id > 0 ) {
// mApp.mDData.updateCalibDayAndComment( id, date, comment );
// setStatus( STATUS_GM );
// // updateDisplay( );
// }
// }
void updateGM( long value, String name )
{
mApp.mDData.updateGMName( mCIDid, mApp.mCID, name );
String id = Long.toString(mCIDid);
// CalibCBlock blk = mApp.mDData.selectGM( mCIDid, mApp.mCID );
mSaveCBlock.setGroup( value );
// if ( mApp.mListRefresh ) {
// mDataAdapter.notifyDataSetChanged();
// } else {
mSaveTextView.setText( id + " <" + name + "> " + mSaveData );
mSaveTextView.setTextColor( mSaveCBlock.color() );
// mSaveTextView.invalidate();
// updateDisplay( ); // FIXME
// }
}
void deleteGM( boolean delete )
{
mApp.mDData.deleteGM( mApp.mCID, mCIDid, delete );
updateDisplay( );
}
@Override
public boolean onSearchRequested()
{
// TDLog.Error( "search requested" );
Intent intent = new Intent( this, TopoDroidPreferences.class );
intent.putExtra( TopoDroidPreferences.PREF_CATEGORY, TopoDroidPreferences.PREF_CATEGORY_CALIB );
startActivity( intent );
return true;
}
@Override
public boolean onKeyDown( int code, KeyEvent event )
{
switch ( code ) {
case KeyEvent.KEYCODE_BACK: // HARDWARE BACK (4)
super.onBackPressed();
return true;
case KeyEvent.KEYCODE_SEARCH:
return onSearchRequested();
case KeyEvent.KEYCODE_MENU: // HARDWRAE MENU (82)
String help_page = getResources().getString( R.string.GMActivity );
if ( help_page != null ) UserManualActivity.showHelpPage( this, help_page );
return true;
// case KeyEvent.KEYCODE_VOLUME_UP: // (24)
// case KeyEvent.KEYCODE_VOLUME_DOWN: // (25)
default:
// TDLog.Error( "key down: code " + code );
}
return false;
}
// ---------------------------------------------------------
private void setMenuAdapter( Resources res )
{
// HOVER
// mMenuAdapter = new MyMenuAdapter( this, this, mMenu, R.layout.menu, new ArrayList< MyMenuItem >() );
mMenuAdapter = new ArrayAdapter<String>(this, R.layout.menu );
for ( int k=0; k<4; ++k ) {
mMenuAdapter.add( res.getString( menus[k] ) );
}
mMenu.setAdapter( mMenuAdapter );
mMenu.invalidate();
}
private void closeMenu()
{
mMenu.setVisibility( View.GONE );
// HOVER
// mMenuAdapter.resetBgColor();
onMenu = false;
}
private void handleMenu( int pos )
{
closeMenu();
int p = 0;
if ( p++ == pos ) { // DISPLAY
mBlkStatus = 1 - mBlkStatus; // 0 --> 1; 1 --> 0
updateDisplay( );
} else if ( p++ == pos ) { // VALIDATE
// Toast.makeText( this, "UNDER CONSTRUCTION", Toast.LENGTH_SHORT ).show();
List< String > list = mApp.mDData.selectDeviceCalibs( mApp.mDevice.mAddress );
list.remove( mApp.myCalib );
if ( list.size() == 0 ) {
Toast.makeText( this, R.string.few_calibs, Toast.LENGTH_SHORT ).show();
} else {
(new CalibValidateListDialog( this, this, list )).show();
}
} else if ( p++ == pos ) { // OPTIONS
Intent intent = new Intent( this, TopoDroidPreferences.class );
intent.putExtra( TopoDroidPreferences.PREF_CATEGORY, TopoDroidPreferences.PREF_CATEGORY_CALIB );
startActivity( intent );
} else if ( p++ == pos ) { // HELP
(new HelpDialog(this, izons, menus, help_icons, help_menus, mNrButton1, menus.length ) ).show();
}
}
// public void notifyDisconnected()
// {
// }
}