/* @file CalibActivity.java
*
* @author marco corvi
* @date may 2012
*
* @brief TopoDroid calib activity
* --------------------------------------------------------
* Copyright This sowftare is distributed under GPL-3.0 or later
* See the file COPYING.
* --------------------------------------------------------
*/
package com.topodroid.DistoX;
import java.util.ArrayList;
import android.app.Activity;
// import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.content.Context;
// import android.content.Intent;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Button;
import android.widget.RadioButton;
import android.view.View;
import android.app.DatePickerDialog;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
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.widget.ListView;
import android.widget.ArrayAdapter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
public class CalibActivity extends Activity
implements OnItemClickListener
, View.OnClickListener
, IExporter
{
private static int izonsno[] = {
0, // R.drawable.iz_save_no,
R.drawable.iz_open_no,
R.drawable.iz_read_no
// R.drawable.iz_export0_no
};
private static int izons[] = {
R.drawable.iz_save,
R.drawable.iz_open,
R.drawable.iz_read
};
BitmapDrawable mBMopen;
BitmapDrawable mBMopen_no;
BitmapDrawable mBMread;
BitmapDrawable mBMread_no;
private static int menus[] = {
R.string.menu_export,
R.string.menu_delete,
R.string.menu_options,
R.string.menu_help
};
private static int help_icons[] = {
R.string.help_save_calib,
R.string.help_open_calib,
R.string.help_coeff
};
private static int help_menus[] = {
R.string.help_export_calib,
R.string.help_delete_calib,
R.string.help_prefs,
R.string.help_help
};
private EditText mEditName;
private Button mEditDate;
// private TextView mEditDevice;
private String mDeviceAddress;
private EditText mEditComment;
MyDateSetListener mDateListener;
private RadioButton mCBAlgoAuto;
private RadioButton mCBAlgoLinear;
private RadioButton mCBAlgoNonLinear;
private RadioButton mCBAlgoMinimum;
private TopoDroidApp mApp;
private boolean isSaved;
private void setButtons( )
{
mButton1[1].setEnabled( isSaved ); // open
if ( 2 < mNrButton1 ) mButton1[2].setEnabled( isSaved ); // coeff (read)
if ( isSaved ) {
mButton1[1].setBackgroundDrawable( mBMopen );
if ( 2 < mNrButton1 ) {
mButton1[2].setBackgroundDrawable( mBMread );
}
} else {
mButton1[1].setBackgroundDrawable( mBMopen_no );
if ( 2 < mNrButton1 ) {
mButton1[2].setBackgroundDrawable( mBMread_no );
}
}
}
// -------------------------------------------------------------------
private Button[] mButton1;
private int mNrButton1 = 0;
// private Button[] mButton2;
HorizontalListView mListView;
HorizontalButtonView mButtonView1;
ListView mMenu;
Button mImage;
// HOVER
// MyMenuAdapter mMenuAdapter;
ArrayAdapter< String > mMenuAdapter;
boolean onMenu;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mApp = (TopoDroidApp)getApplication();
setContentView(R.layout.calib_activity);
mEditName = (EditText) findViewById(R.id.calib_name);
mEditDate = (Button) findViewById(R.id.calib_date);
// mEditDevice = (TextView) findViewById(R.id.calib_device);
mEditComment = (EditText) findViewById(R.id.calib_comment);
mDateListener = new MyDateSetListener( mEditDate );
mEditDate.setOnClickListener( this );
mCBAlgoAuto = (RadioButton) findViewById( R.id.calib_algo_auto );
mCBAlgoLinear = (RadioButton) findViewById( R.id.calib_algo_linear );
mCBAlgoNonLinear = (RadioButton) findViewById( R.id.calib_algo_non_linear );
mCBAlgoMinimum = (RadioButton) findViewById( R.id.calib_algo_minimum );
if ( ! TDSetting.mLevelOverExperimental )
mCBAlgoMinimum.setVisibility( View.GONE );
mListView = (HorizontalListView) findViewById(R.id.listview);
int size = mApp.setListViewHeight( mListView );
Resources res = getResources();
mNrButton1 = 2 + ( TDSetting.mLevelOverNormal? 1 : 0 );
mButton1 = new Button[ mNrButton1 ];
for ( int k=0; k<mNrButton1; ++k ) {
mButton1[k] = MyButton.getButton( this, this, izons[k] );
if ( k == 1 ) { mBMopen = MyButton.getButtonBackground( mApp, res, izons[k] ); }
else if ( k == 2 ) { mBMread = MyButton.getButtonBackground( mApp, res, izons[k] ); }
}
mBMopen_no = MyButton.getButtonBackground( mApp, res, izonsno[1] );
mBMread_no = MyButton.getButtonBackground( mApp, res, izonsno[2] );
mButtonView1 = new HorizontalButtonView( mButton1 );
// mButtonView2 = new HorizontalButtonView( mButton2 );
mListView = (HorizontalListView) findViewById(R.id.listview);
mListView.setAdapter( mButtonView1.mAdapter );
// TDLog.Log( TDLog.LOG_CALIB, "app mCID " + mApp.mCID );
setNameEditable( mApp.mCID >= 0 );
if ( isSaved ) {
CalibInfo info = mApp.getCalibInfo();
mEditName.setText( info.name );
// mEditName.setEditable( false );
mEditDate.setText( info.date );
if ( info.device != null && info.device.length() > 0 ) {
mDeviceAddress = info.device;
} else if ( mApp.distoAddress() != null ) {
mDeviceAddress = mApp.distoAddress();
}
// mEditDevice.setText( mDeviceAddress );
if ( info.comment != null && info.comment.length() > 0 ) {
mEditComment.setText( info.comment );
} else {
mEditComment.setHint( R.string.description );
}
switch ( info.algo ) {
case 0: mCBAlgoAuto.setChecked( true ); break;
case 1: mCBAlgoLinear.setChecked( true ); break;
case 2: mCBAlgoNonLinear.setChecked( true ); break;
case 3: mCBAlgoMinimum.setChecked( true ); break;
default: mCBAlgoAuto.setChecked( true ); break;
}
} else {
mEditName.setHint( R.string.name );
mEditDate.setText( TopoDroidUtil.currentDate() );
mDeviceAddress = mApp.distoAddress();
// mEditDevice.setText( mDeviceAddress );
mEditComment.setHint( R.string.description );
mCBAlgoAuto.setChecked( true );
}
setButtons();
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 );
}
// ---------------------------------------------------------------
@Override
public void onClick(View view)
{
if ( onMenu ) {
closeMenu();
return;
}
// TDLog.Log( TDLog.LOG_INPUT, "onClick(View) " + view.toString() );
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;
} else if ( b == mEditDate ) {
String date = mEditDate.getText().toString();
int y = TopoDroidUtil.dateParseYear( date );
int m = TopoDroidUtil.dateParseMonth( date );
int d = TopoDroidUtil.dateParseDay( date );
new DatePickerDialog( this, mDateListener, y, m, d ).show();
return;
}
int k = 0;
if ( k < mNrButton1 && b == mButton1[k++] ) {
doSave();
} else if ( k < mNrButton1 && b == mButton1[k++] ) {
if ( ! mApp.checkCalibrationDeviceMatch() ) {
// FIXME use alert dialog
Toast.makeText( this, R.string.calib_device_mismatch, Toast.LENGTH_LONG ).show();
}
doOpen();
// } else if ( k < mNrButton1 && b == mButton1[k++] ) { // export
// new CalibExportDialog( this, this ).show();
} else if ( k < mNrButton1 && b == mButton1[k++] ) {
showCoeffs();
// } else if ( k < mNrButton1 && b == mButton1[k++] ) {
// askDelete();
}
}
private void showCoeffs()
{
byte[] coeff = CalibAlgo.stringToCoeff( mApp.mDData.selectCalibCoeff( mApp.mCID ) );
Matrix mG = new Matrix();
Matrix mM = new Matrix();
Vector vG = new Vector();
Vector vM = new Vector();
Vector nL = new Vector();
CalibAlgo.coeffToG( coeff, vG, mG );
CalibAlgo.coeffToM( coeff, vM, mM );
CalibAlgo.coeffToNL( coeff, nL );
CalibResult res = new CalibResult();
mApp.mDData.selectCalibError( mApp.mCID, res );
(new CalibCoeffDialog( this, mApp, vG, mG, vM, mM, nL, null,
res.error, res.stddev, res.max_error, res.iterations, coeff )).show();
}
private void askDelete()
{
TopoDroidAlertDialog.makeAlert( this, getResources(),
getResources().getString( R.string.calib_delete ) + " " + mApp.myCalib + " ?",
new DialogInterface.OnClickListener() {
@Override
public void onClick( DialogInterface dialog, int btn ) {
// TDLog.Log( TDLog.LOG_INPUT, "calib delite" );
doDelete();
}
}
);
}
private void doOpen()
{
Intent openIntent = new Intent( this, GMActivity.class );
startActivity( openIntent );
}
private void doSave( )
{
String name = mEditName.getText().toString().trim();
if ( name == null ) {
String error = getResources().getString( R.string.error_name_required );
mEditName.setError( error );
return;
}
name = TopoDroidUtil.noSpaces( name );
if ( name.length() == 0 ) {
String error = getResources().getString( R.string.error_name_required );
mEditName.setError( error );
return;
}
String date = mEditDate.getText().toString();
String device = mDeviceAddress; // mEditDevice.getText().toString();
String comment = mEditComment.getText().toString();
if ( date != null ) { date = date.trim(); }
if ( device != null ) { device = device.trim(); }
if ( comment != null ) { comment = comment.trim(); }
if ( isSaved ) { // calib already saved
mApp.mDData.updateCalibInfo( mApp.mCID, date, device, comment );
Toast.makeText( this, R.string.calib_updated, Toast.LENGTH_SHORT ).show();
} else { // new calib
name = TopoDroidUtil.noSpaces( name );
if ( name != null && name.length() > 0 ) {
if ( mApp.hasCalibName( name ) ) { // name already exists
// Toast.makeText( this, R.string.calib_exists, Toast.LENGTH_SHORT ).show();
String error = getResources().getString( R.string.calib_exists );
mEditName.setError( error );
} else {
mApp.setCalibFromName( name );
mApp.mDData.updateCalibInfo( mApp.mCID, date, device, comment );
setNameEditable( true );
Toast.makeText( this, R.string.calib_saved, Toast.LENGTH_SHORT ).show();
}
} else {
Toast.makeText( this, R.string.calib_no_name, Toast.LENGTH_SHORT ).show();
}
}
int algo = 0;
if ( mCBAlgoLinear.isChecked() ) algo = 1;
else if ( mCBAlgoNonLinear.isChecked() ) algo = 2;
else if ( mCBAlgoMinimum.isChecked() ) algo = 3;
mApp.mDData.updateCalibAlgo( mApp.mCID, algo );
setButtons();
}
private void setNameEditable( boolean saved )
{
isSaved = saved;
if ( isSaved ) {
mEditName.setFocusable( false );
mEditName.setClickable( false );
mEditName.setKeyListener( null );
// mEditDevice.setFocusable( false );
// mEditDevice.setClickable( false );
// mEditDevice.setKeyListener( null );
}
}
public void doDelete()
{
if ( mApp.mCID < 0 ) return;
mApp.mDData.doDeleteCalib( mApp.mCID );
mApp.setCalibFromName( null );
finish();
}
@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.CalibActivity );
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 );
mMenuAdapter.add( res.getString( menus[0] ) );
if ( TDSetting.mLevelOverBasic ) mMenuAdapter.add( res.getString( menus[1] ) );
mMenuAdapter.add( res.getString( menus[2] ) );
mMenuAdapter.add( res.getString( menus[3] ) );
mMenu.setAdapter( mMenuAdapter );
mMenu.invalidate();
}
private void closeMenu()
{
mMenu.setVisibility( View.GONE );
// HOVER
// mMenuAdapter.resetBgColor();
onMenu = false;
}
private void handleMenu( int pos )
{
closeMenu();
// Toast.makeText(this, item.toString(), Toast.LENGTH_SHORT).show();
int p = 0;
if ( p++ == pos ) { // EXPORT
if ( mApp.myCalib != null ) {
// new CalibExportDialog( this, this ).show();
new ExportDialog( this, this, TDConst.mCalibExportTypes, R.string.title_calib_export ).show();
}
} else if ( TDSetting.mLevelOverBasic && p++ == pos ) { // DELETE
if ( mApp.myCalib != null ) {
askDelete();
}
} 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 doExport( String type )
{
int index = TDConst.calibExportIndex( type );
if ( index >= 0 ) doExport( index, true );
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id)
{
// CharSequence item = ((TextView) view).getText();
if ( mMenu == (ListView)parent ) {
handleMenu( pos );
}
}
private void doExport( int exportType, boolean warn )
{
if ( mApp.mCID < 0 ) {
if ( warn ) {
Toast.makeText( this, R.string.no_calibration, Toast.LENGTH_SHORT).show();
}
} else {
String filename = null;
switch ( exportType ) {
case TDConst.DISTOX_EXPORT_CSV:
filename = mApp.exportCalibAsCsv();
}
if ( warn ) {
if ( filename != null ) {
Toast.makeText( this, getString(R.string.saving_) + filename, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText( this, R.string.saving_file_failed, Toast.LENGTH_SHORT).show();
}
}
}
}
}