package com.lateensoft.pathfinder.toolkit.views;
import java.util.List;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AdapterView.OnItemSelectedListener;
import com.lateensoft.pathfinder.toolkit.R;
import com.lateensoft.pathfinder.toolkit.dao.DataAccessException;
import com.lateensoft.pathfinder.toolkit.db.dao.table.AbilityDAO;
import com.lateensoft.pathfinder.toolkit.db.dao.table.CharacterModelDAO;
import com.lateensoft.pathfinder.toolkit.db.dao.table.CharacterNameDAO;
import com.lateensoft.pathfinder.toolkit.db.dao.table.FluffDAO;
import com.lateensoft.pathfinder.toolkit.model.IdNamePair;
import com.lateensoft.pathfinder.toolkit.model.character.FluffInfo;
import com.lateensoft.pathfinder.toolkit.model.character.PathfinderCharacter;
import com.lateensoft.pathfinder.toolkit.model.character.stats.AbilitySet;
import com.lateensoft.pathfinder.toolkit.model.character.stats.AbilityType;
import com.lateensoft.pathfinder.toolkit.pref.GlobalPrefs;
import com.lateensoft.pathfinder.toolkit.pref.Preferences;
import com.lateensoft.pathfinder.toolkit.util.AbilitySetCalculator;
import com.lateensoft.pathfinder.toolkit.views.character.CharacterAbilitiesFragment;
import roboguice.RoboGuice;
public class PointbuyCalculatorFragment extends BasePageFragment {
private static final String TAG = PointbuyCalculatorFragment.class.getSimpleName();
static final int STR_IDX = 0;
static final int DEX_IDX = 1;
static final int CON_IDX = 2;
static final int INT_IDX = 3;
static final int WIS_IDX = 4;
static final int CHA_IDX = 5;
static final int NUM_ABILITIES = AbilityType.values().length;
static final int CUSTOM_RACE_INDEX = 7;
private static final int CUSTOM_RACE_MOD_SPINNER_OFFSET = 10;
private AbilitySetCalculator abilityCalc;
private HumanRaceModSelectedListener humanRaceListener;
private boolean isHuman;
private Button strIncBtn;
private Button strDecBtn;
private Button dexIncBtn;
private Button dexDecBtn;
private Button conIncBtn;
private Button conDecBtn;
private Button intIncBtn;
private Button intDecBtn;
private Button wisIncBtn;
private Button wisDecBtn;
private Button chaIncBtn;
private Button chaDecBtn;
private Spinner racesSpinner;
private Spinner dialogStrSpinner;
private Spinner dialogDexSpinner;
private Spinner dialogConSpinner;
private Spinner dialogIntSpinner;
private Spinner dialogWisSpinner;
private Spinner dialogChaSpinner;
private CharacterModelDAO characterModelDao;
private CharacterNameDAO characterNameDao;
private FluffDAO fluffDao;
private AbilityDAO abilityDao;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
characterModelDao = new CharacterModelDAO(getContext());
characterNameDao = new CharacterNameDAO(getContext());
fluffDao = new FluffDAO(getContext());
abilityDao = new AbilityDAO(getContext());
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRootView(inflater.inflate(R.layout.fragment_ability_calculator, container, false));
isHuman = true;
IncDecButtonListener buttonListener = new IncDecButtonListener();
strIncBtn = (Button) getRootView().findViewById(R.id.btnIncStr);
strIncBtn.setOnClickListener(buttonListener);
strDecBtn = (Button) getRootView().findViewById(R.id.btnDecStr);
strDecBtn.setOnClickListener(buttonListener);
dexIncBtn = (Button) getRootView().findViewById(R.id.btnIncDex);
dexIncBtn.setOnClickListener(buttonListener);
dexDecBtn = (Button) getRootView().findViewById(R.id.btnDecDex);
dexDecBtn.setOnClickListener(buttonListener);
conIncBtn = (Button) getRootView().findViewById(R.id.btnIncCon);
conIncBtn.setOnClickListener(buttonListener);
conDecBtn = (Button) getRootView().findViewById(R.id.btnDecCon);
conDecBtn.setOnClickListener(buttonListener);
intIncBtn = (Button) getRootView().findViewById(R.id.btnIncInt);
intIncBtn.setOnClickListener(buttonListener);
intDecBtn = (Button) getRootView().findViewById(R.id.btnDecInt);
intDecBtn.setOnClickListener(buttonListener);
wisIncBtn = (Button) getRootView().findViewById(R.id.btnIncWis);
wisIncBtn.setOnClickListener(buttonListener);
wisDecBtn = (Button) getRootView().findViewById(R.id.btnDecWis);
wisDecBtn.setOnClickListener(buttonListener);
chaIncBtn = (Button) getRootView().findViewById(R.id.btnIncCha);
chaIncBtn.setOnClickListener(buttonListener);
chaDecBtn = (Button) getRootView().findViewById(R.id.btnDecCha);
chaDecBtn.setOnClickListener(buttonListener);
abilityCalc = new AbilitySetCalculator();
racesSpinner = (Spinner) getRootView().findViewById(R.id.races_spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(),
R.array.races_array, R.layout.spinner_centered);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(R.layout.spinner_centered);
// Apply the adapter to the spinner
racesSpinner.setAdapter(adapter);
racesSpinner.setOnItemSelectedListener(new RaceItemSelectedListener());
humanRaceListener = new HumanRaceModSelectedListener();
getRootView().findViewById(R.id.raceStr).setOnClickListener(humanRaceListener);
getRootView().findViewById(R.id.raceDex).setOnClickListener(humanRaceListener);
getRootView().findViewById(R.id.raceCon).setOnClickListener(humanRaceListener);
getRootView().findViewById(R.id.raceInt).setOnClickListener(humanRaceListener);
getRootView().findViewById(R.id.raceWis).setOnClickListener(humanRaceListener);
getRootView().findViewById(R.id.raceCha).setOnClickListener(humanRaceListener);
updateAbilityViews();
return getRootView();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.pointbuy_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void updateTitle() {
setTitle(R.string.title_activity_ability_calc);
setSubtitle(null);
}
private class RaceItemSelectedListener implements OnItemSelectedListener {
@Override public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// An item was selected. You can retrieve the selected item using
// parent.getItemAtPosition(pos)
if(parent.getSelectedItemPosition() != CUSTOM_RACE_INDEX) {
isHuman = abilityCalc.setRacialMods((int) parent.getSelectedItemId(), getContext());
updateAbilityViews();
} else {
// Custom race
showCustomRaceDialog();
}
}
@Override public void onNothingSelected(AdapterView<?> parent) {}
}
private void showCustomRaceDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
LayoutInflater inflater = LayoutInflater.from(getContext());
View dialogView = inflater.inflate(R.layout.calculator_custom_race_dialog, null);
dialogStrSpinner = (Spinner) dialogView.findViewById(R.id.spCustomStrMod);
dialogDexSpinner = (Spinner) dialogView.findViewById(R.id.spCustomDexMod);
dialogConSpinner = (Spinner) dialogView.findViewById(R.id.spCustomConMod);
dialogIntSpinner = (Spinner) dialogView.findViewById(R.id.spCustomIntMod);
dialogWisSpinner = (Spinner) dialogView.findViewById(R.id.spCustomWisMod);
dialogChaSpinner = (Spinner) dialogView.findViewById(R.id.spCustomChaMod);
setupCustomRaceSpinner(dialogStrSpinner);
setupCustomRaceSpinner(dialogDexSpinner);
setupCustomRaceSpinner(dialogConSpinner);
setupCustomRaceSpinner(dialogIntSpinner);
setupCustomRaceSpinner(dialogWisSpinner);
setupCustomRaceSpinner(dialogChaSpinner);
OnCustomRaceModSetListener customRaceModSetListener = new OnCustomRaceModSetListener();
builder.setView(dialogView)
.setPositiveButton(R.string.ok_button_text, customRaceModSetListener)
.setTitle(R.string.calc_custom_race_dialog_title);
AlertDialog alert = builder.create();
alert.show();
}
private class OnCustomRaceModSetListener implements DialogInterface.OnClickListener {
public void onClick(DialogInterface dialogInterface, int selection) {
isHuman = false;
getCustomRacialModSetFromDialog();
}
}
private void getCustomRacialModSetFromDialog() {
int[] mods = new int[NUM_ABILITIES];
mods[STR_IDX] = dialogStrSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
mods[DEX_IDX] = dialogDexSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
mods[CON_IDX] = dialogConSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
mods[INT_IDX] = dialogIntSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
mods[WIS_IDX] = dialogWisSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
mods[CHA_IDX] = dialogChaSpinner.getSelectedItemPosition() - CUSTOM_RACE_MOD_SPINNER_OFFSET;
abilityCalc.setCustomRaceMods(mods);
updateAbilityViews();
}
private void setupCustomRaceSpinner(Spinner spinner) {
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(),
R.array.calc_custom_race_mod_options, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(R.layout.spinner_plain);
spinner.setAdapter(adapter);
spinner.setSelection(CUSTOM_RACE_MOD_SPINNER_OFFSET);
}
private class HumanRaceModSelectedListener implements OnClickListener {
public void onClick(View v) {
int id = v.getId();
if(!isHuman) {
return;
}
switch (id) {
case R.id.raceStr:
abilityCalc.setHumanRacialMods(STR_IDX, getContext());
break;
case R.id.raceDex:
abilityCalc.setHumanRacialMods(DEX_IDX, getContext());
break;
case R.id.raceCon:
abilityCalc.setHumanRacialMods(CON_IDX, getContext());
break;
case R.id.raceInt:
abilityCalc.setHumanRacialMods(INT_IDX, getContext());
break;
case R.id.raceWis:
abilityCalc.setHumanRacialMods(WIS_IDX, getContext());
break;
case R.id.raceCha:
abilityCalc.setHumanRacialMods(CHA_IDX, getContext());
break;
}
updateAbilityViews();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mi_export_to_new:
PathfinderCharacter character = PathfinderCharacter.newDefaultCharacter("From calc");
abilityCalc.setCalculatedAbilityScores(character.getAbilitySet());
Resources r = getResources();
character.getFluff().setRace(r.getStringArray(R.array.races_array)
[racesSpinner.getSelectedItemPosition()]);
try {
characterModelDao.add(character);
setSelectedCharacter(character.getId());
switchToPage(CharacterAbilitiesFragment.class);
} catch (DataAccessException e) {
e.printStackTrace();
}
break;
case R.id.mi_export_to_existing:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getString(R.string.select_character_dialog_header));
List<IdNamePair> characterEntries = characterNameDao.findAll();
String[] characterNames = IdNamePair.nameArray(characterEntries);
OnCharacterExportSelectListener exportListener =
new OnCharacterExportSelectListener(characterEntries);
builder.setSingleChoiceItems(characterNames, -1,
exportListener).setPositiveButton(R.string.ok_button_text, exportListener)
.setNegativeButton(R.string.cancel_button_text, exportListener);
AlertDialog alert = builder.create();
alert.show();
break;
}
return true;
}
private void setSelectedCharacter(long characterId) {
Preferences preferences = RoboGuice.getInjector(getContext()).getInstance(Preferences.class);
preferences.put(GlobalPrefs.SELECTED_CHARACTER_ID, characterId);
}
private class OnCharacterExportSelectListener implements DialogInterface.OnClickListener {
long characterIdSelectedInDialog;
List<IdNamePair> _characterList;
public OnCharacterExportSelectListener(List<IdNamePair> characterIds) {
_characterList = characterIds;
characterIdSelectedInDialog = 0;
}
public void onClick(DialogInterface dialogInterface, int selection) {
switch (selection) {
case DialogInterface.BUTTON_POSITIVE:
if (characterIdSelectedInDialog > 0) {
FluffInfo fluff = fluffDao.find(characterIdSelectedInDialog);
AbilitySet abilities = new AbilitySet(abilityDao.findAllForOwner(characterIdSelectedInDialog), null);
abilityCalc.setCalculatedAbilityScores(abilities);
Resources r = getResources();
fluff.setRace(r.getStringArray(R.array.races_array)
[racesSpinner.getSelectedItemPosition()]);
try {
for (int i = 0; i < abilities.size(); i++) {
abilityDao.update(characterIdSelectedInDialog, abilities.getAbilityAtIndex(i));
}
fluffDao.update(characterIdSelectedInDialog, fluff);
setSelectedCharacter(characterIdSelectedInDialog);
switchToPage(CharacterAbilitiesFragment.class);
} catch (DataAccessException e) {
String message = "Failed to update character";
Log.e(TAG, message, e);
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
}
}
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
default:
// Set the currently selected character in the dialog
characterIdSelectedInDialog = _characterList.get(selection).getId();
break;
}
}
}
private void updateAbilityViews() {
TextView textView;
final int[] modIds = {R.id.strMod, R.id.dexMod, R.id.conMod, R.id.intMod, R.id.wisMod, R.id.chaMod};
final int[] finalScoreIds = {R.id.finStr, R.id.finDex, R.id.finCon, R.id.finInt, R.id.finWis, R.id.finCha};
final int[] baseScoreIds = {R.id.baseStr, R.id.baseDex, R.id.baseCon, R.id.baseInt, R.id.baseWis, R.id.baseCha};
final int[] racialModIds = {R.id.raceStr, R.id.raceDex, R.id.raceCon, R.id.raceInt, R.id.raceWis, R.id.raceCha};
for(int i = 0; i < NUM_ABILITIES; i++) {
textView = (TextView) getRootView().findViewById(modIds[i]);
textView.setText(Integer.toString(abilityCalc.getModPostRaceMod(i)));
textView = (TextView) getRootView().findViewById(baseScoreIds[i]);
textView.setText(Integer.toString(abilityCalc.getBaseScore(i)));
textView = (TextView) getRootView().findViewById(racialModIds[i]);
textView.setText(Integer.toString(abilityCalc.getRaceMod(i)));
textView = (TextView) getRootView().findViewById(finalScoreIds[i]);
textView.setText(Integer.toString(abilityCalc.getScorePostRaceMod(i)));
textView = (TextView) getRootView().findViewById(R.id.textCost);
textView.setText(Integer.toString(abilityCalc.getPointBuyCost()));
}
}
private class IncDecButtonListener implements Button.OnClickListener {
@Override
public void onClick(View v) {
int abilityIndex = 0;
boolean isInc = true;
switch(v.getId()) {
case R.id.btnIncStr:
abilityIndex = STR_IDX;
break;
case R.id.btnDecStr:
abilityIndex = STR_IDX;
isInc = false;
break;
case R.id.btnIncDex:
abilityIndex = DEX_IDX;
break;
case R.id.btnDecDex:
abilityIndex = DEX_IDX;
isInc = false;
break;
case R.id.btnIncCon:
abilityIndex = CON_IDX;
break;
case R.id.btnDecCon:
abilityIndex = CON_IDX;
isInc = false;
break;
case R.id.btnIncInt:
abilityIndex = INT_IDX;
break;
case R.id.btnDecInt:
abilityIndex = INT_IDX;
isInc = false;
break;
case R.id.btnIncWis:
abilityIndex = WIS_IDX;
break;
case R.id.btnDecWis:
abilityIndex = WIS_IDX;
isInc = false;
break;
case R.id.btnIncCha:
abilityIndex = CHA_IDX;
break;
case R.id.btnDecCha:
abilityIndex = CHA_IDX;
isInc = false;
break;
}
if (isInc) {
abilityCalc.incAbilityScore(abilityIndex);
} else {
abilityCalc.decAbilityScore(abilityIndex);
}
updateAbilityViews();
}
}
}