package net.osmand.plus;
import net.osmand.IProgress;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ProgressImplementation implements IProgress {
private static final int HANDLER_START_TASK = OsmAndConstants.UI_HANDLER_PROGRESS + 1;
private static final int HADLER_UPDATE_PROGRESS = OsmAndConstants.UI_HANDLER_PROGRESS + 2;
private String taskName;
private int progress;
private int deltaProgress;
private int work;
private String message = ""; //$NON-NLS-1$
private Handler mViewUpdateHandler;
private Thread run;
private Context context;
private ProgressDialog dialog = null;
private ProgressBar progressBar = null;
private Runnable finishRunnable = null;
private final boolean cancelable;
private TextView tv;
public ProgressImplementation(Context ctx, ProgressDialog dlg, boolean cancelable) {
this.cancelable = cancelable;
context = ctx;
setDialog(dlg);
mViewUpdateHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case HANDLER_START_TASK:
if (dialog != null) {
dialog.setMessage(message);
if (isIndeterminate()) {
dialog.setMax(1);
dialog.setIndeterminate(true);
} else {
dialog.setIndeterminate(false);
dialog.setMax(work);
}
dialog.show();
}
if (tv != null) {
tv.setText(message);
}
if (progressBar != null) {
if (isIndeterminate()) {
progressBar.setMax(1);
progressBar.setIndeterminate(true);
} else {
progressBar.setIndeterminate(false);
progressBar.setMax(work);
}
}
break;
case HADLER_UPDATE_PROGRESS:
if (dialog != null) {
dialog.setProgress(msg.arg1);
} else if (progressBar != null) {
progressBar.setProgress(msg.arg1);
}
break;
}
}
};
}
public ProgressImplementation(ProgressDialog dlg, boolean cancelable){
this(dlg.getContext(), dlg, cancelable);
}
public static ProgressImplementation createProgressDialog(Context ctx, String title, String message, int style) {
return createProgressDialog(ctx, title, message, style, null);
}
public static ProgressImplementation createProgressDialog(Context ctx, String title, String message, int style, final DialogInterface.OnCancelListener listener) {
ProgressDialog dlg = new ProgressDialog(ctx) {
@Override
public void cancel() {
if(listener != null) {
listener.onCancel(this);
} else {
super.cancel();
}
}
};
dlg.setTitle(title);
dlg.setMessage(message);
dlg.setIndeterminate(style == ProgressDialog.STYLE_HORIZONTAL); // re-set in mViewUpdateHandler.handleMessage above
dlg.setCancelable(true);
// we'd prefer a plain progress bar without numbers,
// but that is only available starting from API level 11
try {
ProgressDialog.class
.getMethod("setProgressNumberFormat", new Class[] { String.class })
.invoke(dlg, (String)null);
} catch (NoSuchMethodException nsme) {
// failure, must be older device
} catch (IllegalAccessException nsme) {
// failure, must be older device
} catch (java.lang.reflect.InvocationTargetException nsme) {
// failure, must be older device
}
dlg.setProgressStyle(style);
return new ProgressImplementation(dlg, true);
}
public void setProgressBar(TextView tv, ProgressBar progressBar, Runnable finish) {
this.tv = tv;
this.progressBar = progressBar;
this.finishRunnable = finish;
}
public void setDialog(ProgressDialog dlg){
if(dlg != null){
if(cancelable){
dlg.setOnCancelListener(new OnCancelListener(){
@Override
public void onCancel(DialogInterface dialog) {
if(run != null){
run.stop();
}
}
});
}
this.dialog = dlg;
}
}
public void setRunnable(String threadName, Runnable run){
this.run = new Thread(run, threadName);
}
public void run(){
if(run == null){
throw new IllegalStateException();
}
run.start();
}
@Override
public void progress(int deltaWork) {
if (!isIndeterminate() && dialog != null) {
this.deltaProgress += deltaWork;
//update only each percent
if ((deltaProgress > (work / 100)) || ((progress + deltaProgress) >= work)) {
this.progress += deltaProgress;
this.deltaProgress = 0;
updateProgressMessage(this.progress);
}
}
}
private void updateProgressMessage(int aProgress) {
Message msg = mViewUpdateHandler.obtainMessage();
msg.arg1 = aProgress;
msg.what = HADLER_UPDATE_PROGRESS;
mViewUpdateHandler.sendMessage(msg);
}
@Override
public void remaining(int remainingWork) {
int newprogress = work - remainingWork;
progress(newprogress - this.progress);
}
@Override
public boolean isIndeterminate(){
return work == -1;
}
@Override
public void startTask(String taskName, int work) {
if(taskName == null){
taskName = ""; //$NON-NLS-1$
}
message = taskName;
this.taskName = taskName;
startWork(work);
mViewUpdateHandler.sendEmptyMessage(HANDLER_START_TASK);
}
@Override
public void finishTask() {
work = -1;
progress = 0;
if (taskName != null) {
message = context.getResources().getString(R.string.finished_task) +" : "+ taskName; //$NON-NLS-1$
mViewUpdateHandler.sendEmptyMessage(HANDLER_START_TASK);
}
}
@Override
public boolean isInterrupted() {
return false;
}
public ProgressDialog getDialog() {
return dialog;
}
public Runnable getFinishRunnable() {
return finishRunnable;
}
@Override
public void startWork(int work) {
this.work = work;
if (this.work == 0) {
this.work = 1;
}
progress = 0;
deltaProgress = 0;
}
}