package cri.sanity.screen;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceCategory;
import android.preference.CheckBoxPreference;
import android.provider.CallLog.Calls;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import cri.sanity.*;
import cri.sanity.util.*;
public class NumsActivity extends ScreenActivity
{
private static final String SEP = FilterActivity.SEP;
private static final int CODE_CALLOG = 1;
private static final int MAX_CALLOGS = 30;
private PreferenceCategory prefGroup;
private Stack<Pref> selected = new Stack<Pref>();
private Map<String,Pref> prefs = new HashMap<String,Pref>();
private List<String> callog;
private String sect;
private boolean changed;
//---- overriding
@Override
public void onCreate(Bundle savedInstanceState)
{
skipAllKeys = true;
screener(NumsActivity.class, R.xml.filter_nums, R.layout.img_list);
super.onCreate(savedInstanceState);
changed = false;
prefGroup = (PreferenceCategory)pref("filter_nums");
Intent i = getIntent();
sect = i.getStringExtra(FilterActivity.EXTRA_SECT);
String t = i.getStringExtra(FilterActivity.EXTRA_TITLE);
if(!A.empty(t))
prefGroup.setTitle(prefGroup.getTitle()+" ("+t+ ')');
String nums = A.gets(keyAll());
if(A.empty(nums))
A.toast(R.string.msg_empty_list);
else
for(String num : nums.split(SEP))
addnum(num);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.nums, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId()) {
case R.id.addnew : addnew(); break;
case R.id.callog : callog(); break;
case R.id.change : change(); break;
case R.id.del : delete(); break;
case R.id.selall : selall(); break;
case R.id.selnone: selnone(); break;
case R.id.canc : canc(); break;
default: return super.onOptionsItemSelected(item);
}
return true;
}
@Override
public void onBackPressed()
{
if(changed) {
for(String num : A.gets(keyAll()).split(SEP))
A.del(keySect(num.trim()));
String nums = "";
final int n = prefGroup.getPreferenceCount();
if(n > 0) {
String num = ((Pref)prefGroup.getPreference(0)).getNum();
A.put(keySect(num), true);
final StringBuilder sb = new StringBuilder(num);
for(int i=1; i<n; i++) {
num = ((Pref)prefGroup.getPreference(i)).getNum();
A.put(keySect(num), true);
sb.append(SEP).append(num);
}
nums = sb.toString();
}
A.put(keyAll(), nums).putc(keyCount(), n);
}
Intent i = new Intent();
i.putExtra(FilterActivity.EXTRA_SECT, prefGroup.getPreferenceCount());
setResult(RESULT_OK, i);
super.onBackPressed();
}
@Override
public void onActivityResult(int code, int res, Intent i)
{
if(i==null || code!=CODE_CALLOG) return;
}
//---- private api
private String keyAll() { return "filter_nums_"+sect; }
private String keyCount() { return "filter_nums_count_"+sect; }
private String keySect(String val) { return "filter_num_"+val+sect; }
private void addnum(String num)
{
Pref pref = new Pref(num);
prefs.put(num, pref);
prefGroup.addPreference(pref);
}
private void callog()
{
if(callog == null) {
Cursor c = A.resolver().query(Calls.CONTENT_URI,
new String[]{ Calls.NUMBER }, Calls.CACHED_NAME+" IS NULL", null, Calls.DEFAULT_SORT_ORDER
);
int n = Math.min(c.getCount(), MAX_CALLOGS);
callog = new Vector<String>(n);
Map<String,Integer> read = new HashMap<String,Integer>(n);
if(c.moveToFirst()) {
final int col = c.getColumnIndex(Calls.NUMBER);
n = 0;
do {
final String num = c.getString(col);
if(num==null || num.length()<3 || prefs.get(num)!=null || read.get(num)!=null) continue;
callog.add(num);
read.put(num, 1);
if(++n > MAX_CALLOGS) break;
} while(c.moveToNext());
}
c.close();
}
final int n = callog.size();
if(n <= 0)
A.toast(R.string.msg_callog_empty);
else
Alert.choose(A.s(R.string.msg_callog_new), (String[])callog.toArray(new String[n]), new Alert.Click() {
@Override
public void on() {
addnum(callog.get(which).toString());
changed = true;
}
});
}
private void addnew()
{
Alert.edit(A.s(R.string.msg_nums_edit), PrefixNum.get(), new Alert.Edited() {
@Override
public void on(String num) {
num = num.trim();
if(num.length() < 2) { A.toast(R.string.err_name); return; }
if(prefs.get(num) != null) { A.toast(String.format(A.s(R.string.err_exists), num)); return; }
addnum(num);
changed = true;
}
}).setInputType(InputType.TYPE_CLASS_PHONE);
}
private void change()
{
if(selected.isEmpty()) return;
final Pref prefSel = selected.peek();
final String numSel = prefSel.getNum();
Alert.edit(A.s(R.string.msg_nums_edit), numSel, new Alert.Edited() {
@Override
public void on(String num) {
num = num.trim();
if(num.length() < 2) { A.toast(R.string.err_name); return; }
if(num.equals(numSel)) return;
if(prefs.get(num) != null) { A.toast(String.format(A.s(R.string.err_exists), num)); return; }
prefSel.setNum(num);
changed = true;
}
}).setInputType(InputType.TYPE_CLASS_PHONE);
}
private void delete()
{
final int n = selected.size();
if(n < 1) return;
Alert.msg(n>1? String.format(A.s(R.string.ask_del_all), n+"") : A.s(R.string.ask_del_one),
new Alert.Click() {
@SuppressWarnings("unchecked")
public void on() {
if(selected.isEmpty()) return;
for(Pref p : (Stack<Pref>)selected.clone()) {
prefs.remove(p.getNum());
prefGroup.removePreference(p);
selected.remove(p);
}
changed = true;
}
},
null,
Alert.OKCANC
);
}
private void selall()
{
final int n = prefGroup.getPreferenceCount();
if(n < 1) return;
selected.clear();
for(int i=0; i<n; i++) {
final Pref p = (Pref)prefGroup.getPreference(i);
p.setChecked(true);
selected.add(p);
}
if(n > 2)
A.toast(String.format(A.s(R.string.msg_selected_all), n+""));
}
private void selnone()
{
for(Pref p : selected) p.setChecked(false);
selected.clear();
}
private void canc()
{
if(!changed) { finish(); return; }
Alert.msg(
A.s(R.string.ask_canc_all),
new Alert.Click(){ public void on(){ changed = false; dismiss(); finish(); }},
null,
Alert.OKCANC
);
}
//---- inner classes
private class Pref extends CheckBoxPreference implements OnPreferenceChangeListener
{
Pref(String num) {
super(NumsActivity.this);
setPersistent(false);
setNum(num);
setOnPreferenceChangeListener(this);
}
private String getNum() { return getTitle().toString(); }
private void setNum(String num) { setTitle(num.trim()); }
@Override
public boolean onPreferenceChange(Preference p, Object v) {
if((Boolean)v) selected.push(this);
else selected.remove(this);
return true;
}
}
}