/*
DroidFish - An Android chess program.
Copyright (C) 2011 Peter Ă–sterlund, peterosterlund2@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.if3games.chessonline.activities;
import java.io.File;
import java.util.Locale;
import java.util.Vector;
import com.if3games.chessonline.ColorTheme;
import com.if3games.chessonline.R;
import com.if3games.chessonline.Util;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.DialogInterface.OnCancelListener;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class LoadScid extends ListActivity {
private static final class GameInfo {
String summary = "";
int gameId = -1;
public String toString() {
StringBuilder sb = new StringBuilder(128);
sb.append(gameId+1);
sb.append(". ");
sb.append(summary);
return sb.toString();
}
}
private static Vector<GameInfo> gamesInFile = new Vector<GameInfo>();
private static boolean cacheValid = false;
private String fileName;
private ProgressDialog progress;
private SharedPreferences settings;
private int defaultItem = 0;
private String lastFileName = "";
private long lastModTime = -1;
Thread workThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settings = PreferenceManager.getDefaultSharedPreferences(this);
if (savedInstanceState != null) {
defaultItem = savedInstanceState.getInt("defaultScidItem");
lastFileName = savedInstanceState.getString("lastScidFileName");
if (lastFileName == null) lastFileName = "";
lastModTime = savedInstanceState.getLong("lastScidModTime");
} else {
defaultItem = settings.getInt("defaultScidItem", 0);
lastFileName = settings.getString("lastScidFileName", "");
lastModTime = settings.getLong("lastScidModTime", 0);
}
Intent i = getIntent();
String action = i.getAction();
fileName = i.getStringExtra("org.petero.droidfish.pathname");
if (action.equals("org.petero.droidfish.loadScid")) {
showDialog(PROGRESS_DIALOG);
final LoadScid lpgn = this;
workThread = new Thread(new Runnable() {
public void run() {
if (!readFile())
return;
runOnUiThread(new Runnable() {
public void run() {
lpgn.showList();
}
});
}
});
workThread.start();
} else if (action.equals("org.petero.droidfish.loadScidNextGame") ||
action.equals("org.petero.droidfish.loadScidPrevGame")) {
boolean next = action.equals("org.petero.droidfish.loadScidNextGame");
final int loadItem = defaultItem + (next ? 1 : -1);
if (loadItem < 0) {
Toast.makeText(getApplicationContext(), R.string.no_prev_game,
Toast.LENGTH_SHORT).show();
setResult(RESULT_CANCELED);
finish();
} else {
workThread = new Thread(new Runnable() {
public void run() {
if (!readFile())
return;
runOnUiThread(new Runnable() {
public void run() {
if (loadItem >= gamesInFile.size()) {
Toast.makeText(getApplicationContext(), R.string.no_next_game,
Toast.LENGTH_SHORT).show();
setResult(RESULT_CANCELED);
finish();
} else {
defaultItem = loadItem;
sendBackResult(gamesInFile.get(loadItem));
}
}
});
}
});
workThread.start();
}
} else { // Unsupported action
setResult(RESULT_CANCELED);
finish();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("defaultScidItem", defaultItem);
outState.putString("lastScidFileName", lastFileName);
outState.putLong("lastScidModTime", lastModTime);
}
@Override
protected void onPause() {
Editor editor = settings.edit();
editor.putInt("defaultScidItem", defaultItem);
editor.putString("lastScidFileName", lastFileName);
editor.putLong("lastScidModTime", lastModTime);
editor.commit();
super.onPause();
}
@Override
protected void onDestroy() {
if (workThread != null) {
workThread.interrupt();
try {
workThread.join();
} catch (InterruptedException e) {
}
workThread = null;
}
super.onDestroy();
}
private final void showList() {
progress.dismiss();
final ArrayAdapter<GameInfo> aa =
new ArrayAdapter<GameInfo>(this, R.layout.select_game_list_item, gamesInFile) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (view instanceof TextView) {
int fg = ColorTheme.instance().getColor(ColorTheme.FONT_FOREGROUND);
((TextView) view).setTextColor(fg);
}
return view;
}
};
setListAdapter(aa);
ListView lv = getListView();
Util.overrideFonts(lv);
lv.setSelectionFromTop(defaultItem, 0);
lv.setFastScrollEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
defaultItem = pos;
sendBackResult(aa.getItem(pos));
}
});
}
final static int PROGRESS_DIALOG = 0;
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG:
progress = new ProgressDialog(this);
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progress.setTitle(R.string.reading_scid_file);
progress.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Thread thr = workThread;
if (thr != null)
thr.interrupt();
}
});
return progress;
default:
return null;
}
}
private final boolean readFile() {
if (!fileName.equals(lastFileName))
defaultItem = 0;
long modTime = new File(fileName).lastModified();
if (cacheValid && (modTime == lastModTime) && fileName.equals(lastFileName))
return true;
lastModTime = modTime;
lastFileName = fileName;
gamesInFile.clear();
Cursor cursor = getListCursor();
if (cursor != null) {
int noGames = cursor.getCount();
gamesInFile.ensureCapacity(noGames);
int percent = -1;
if (cursor.moveToFirst()) {
addGameInfo(cursor);
int gameNo = 1;
while (cursor.moveToNext()) {
if (Thread.currentThread().isInterrupted()) {
setResult(RESULT_CANCELED);
finish();
return false;
}
addGameInfo(cursor);
gameNo++;
final int newPercent = (int)(gameNo * 100 / noGames);
if (newPercent > percent) {
percent = newPercent;
if (progress != null) {
runOnUiThread(new Runnable() {
public void run() {
progress.setProgress(newPercent);
}
});
}
}
}
}
}
cacheValid = true;
return true;
}
private int idIdx;
private int summaryIdx;
private Cursor getListCursor() {
String scidFileName = fileName.substring(0, fileName.indexOf("."));
String[] proj = new String[]{"_id", "summary"};
try {
Cursor cursor = managedQuery(Uri.parse("content://org.scid.database.scidprovider/games"),
proj, scidFileName, null, null);
idIdx = cursor.getColumnIndex("_id");
summaryIdx = cursor.getColumnIndex("summary");
return cursor;
} catch (Throwable t) {
return null;
}
}
private Cursor getOneGameCursor(int gameId) {
String scidFileName = fileName.substring(0, fileName.indexOf("."));
String[] proj = new String[]{"pgn"};
try {
String uri = String.format(Locale.US, "content://org.scid.database.scidprovider/games/%d", gameId);
Cursor cursor = managedQuery(Uri.parse(uri),
proj, scidFileName, null, null);
return cursor;
} catch (Throwable t) {
return null;
}
}
private void addGameInfo(Cursor cursor) {
GameInfo gi = new GameInfo();
gi.gameId = cursor.getInt(idIdx);
gi.summary = cursor.getString(summaryIdx);
gamesInFile.add(gi);
}
private final void sendBackResult(GameInfo gi) {
if (gi.gameId >= 0) {
Cursor cursor = getOneGameCursor(gi.gameId);
if (cursor != null && cursor.moveToFirst()) {
String pgn = cursor.getString(cursor.getColumnIndex("pgn"));
if (pgn != null && pgn.length() > 0) {
setResult(RESULT_OK, (new Intent()).setAction(pgn));
finish();
return;
}
}
}
setResult(RESULT_CANCELED);
finish();
}
}