package com.jobmineplus.mobile.widgets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Locale; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnShowListener; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Spinner; import com.jobmineplus.mobile.R; import com.jobmineplus.mobile.exceptions.JbmnplsParsingException; public class JobSearchDialog extends Builder implements android.content.DialogInterface.OnClickListener, OnItemSelectedListener, OnShowListener { private final AlertDialog dialog; // ======================= // Variable Declaration // ======================= private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy", Locale.getDefault()); public static List<String> DISCIPLINES; public static List<String> DISCIPLINES_CODES; OnJobSearchListener listener; JobSearchProperties properties; Context ctx; Spinner disciplines1Spinner; Spinner disciplines2Spinner; Spinner disciplines3Spinner; Spinner termSpinner; Spinner locationSpinner; Spinner typeSpinner; Spinner filterSpinner; EditText employerText; EditText jobTitleText; CheckBox juniorChkbx; CheckBox intermediateChkbx; CheckBox seniorChkbx; CheckBox bachelorChkbx; CheckBox mastersChkbx; CheckBox phdChkbx; public JobSearchDialog(Context context) { super(context); ctx = context; setPositiveButton("Search", null); setNegativeButton(android.R.string.cancel, this); dialog = create(); dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); dialog.setOnShowListener(this); LayoutInflater inflater = dialog.getLayoutInflater(); View view = inflater.inflate(R.layout.job_search_dialog, null); dialog.setView(view); // Sets the dialog with initial data disciplines1Spinner = (Spinner)view.findViewById(R.id.job_search_disciples1); disciplines2Spinner = (Spinner)view.findViewById(R.id.job_search_disciples2); disciplines3Spinner = (Spinner)view.findViewById(R.id.job_search_disciples3); termSpinner = (Spinner)view.findViewById(R.id.job_search_term); locationSpinner = (Spinner)view.findViewById(R.id.job_search_location); filterSpinner = (Spinner)view.findViewById(R.id.job_search_filter); typeSpinner = (Spinner)view.findViewById(R.id.job_search_type); employerText = (EditText)view.findViewById(R.id.job_search_employer); jobTitleText = (EditText)view.findViewById(R.id.job_search_title); juniorChkbx = (CheckBox)view.findViewById(R.id.job_search_junior); intermediateChkbx = (CheckBox)view.findViewById(R.id.job_search_intermediate); seniorChkbx = (CheckBox)view.findViewById(R.id.job_search_senior); bachelorChkbx = (CheckBox)view.findViewById(R.id.job_search_bachelor); mastersChkbx = (CheckBox)view.findViewById(R.id.job_search_masters); phdChkbx = (CheckBox)view.findViewById(R.id.job_search_phD); // Attach the events disciplines1Spinner.setOnItemSelectedListener(this); disciplines2Spinner.setOnItemSelectedListener(this); disciplines3Spinner.setOnItemSelectedListener(this); termSpinner.setOnItemSelectedListener(this); locationSpinner.setOnItemSelectedListener(this); filterSpinner.setOnItemSelectedListener(this); typeSpinner.setOnItemSelectedListener(this); if (DISCIPLINES == null) { DISCIPLINES = Arrays.asList(ctx.getResources().getStringArray(R.array.job_search_disciplines)); DISCIPLINES_CODES = Arrays.asList(ctx.getResources() .getStringArray(R.array.job_search_disciplines_values)); } } public static String getDisciplineCodeFromName(String name) { int index = name.equals("") ? 0 : DISCIPLINES.indexOf(name); return DISCIPLINES_CODES.get(index); } public boolean isShowing() { return dialog.isShowing(); } @Override public AlertDialog show() { dialog.show(); return dialog; } public void setProperties(JobSearchProperties prop) { properties = prop; setDisciplineSpinner(disciplines1Spinner, prop.disciplines1.get()); setDisciplineSpinner(disciplines2Spinner, prop.disciplines2.get()); setDisciplineSpinner(disciplines3Spinner, prop.disciplines3.get()); setSpinnerDefaultIfEmptyOrName(locationSpinner, prop.location.get()); setSpinnerSelectionByName(filterSpinner, prop.filter.get().toString()); setJobTypeSpinner(prop.jobType.get()); employerText.setText(prop.employer.get()); jobTitleText.setText(prop.title.get()); juniorChkbx.setChecked(prop.levelJunior.get()); intermediateChkbx.setChecked(prop.levelIntermediate.get()); seniorChkbx.setChecked(prop.levelSenior.get()); bachelorChkbx.setChecked(prop.levelBachelors.get()); mastersChkbx.setChecked(prop.levelMasters.get()); phdChkbx.setChecked(prop.levelPhD.get()); populateTermSpinner(prop.term.get()); } public void setJobTypeSpinner(JobSearchProperties.JOBTYPE type) { setSpinnerSelectionByName(typeSpinner, type.toString()); } public void setOnJobSearchListener(OnJobSearchListener jobListener) { listener = jobListener; } private void setDisciplineSpinner(Spinner spinner, String name) { // This fixes the disciplines when Waterloo cannot spell unspecified correctly name = name.replaceAll("unspecfied", "unspecified"); setSpinnerDefaultIfEmptyOrName(spinner, name); } private void setSpinnerDefaultIfEmptyOrName(Spinner spinner, String name) { if (name.equals("")) { spinner.setSelection(0); } else { setSpinnerSelectionByName(spinner, name); } } private void setSpinnerSelectionByName(Spinner spinner, String name) { String findName = name.replaceAll(" ", ""); for (int i = 0; i < spinner.getCount(); i++) { String posName = spinner.getItemAtPosition(i).toString().replaceAll(" ", ""); if (posName.equalsIgnoreCase(findName)) { spinner.setSelection(i); return; } } throw new JbmnplsParsingException("Cannot find the name " + name + " in the spinner"); } public void dismiss() { dialog.dismiss(); } @Override public void onClick(DialogInterface dialog, int which) { if (which == Dialog.BUTTON_NEGATIVE) { listener.onCancel(); // Reject any changes to the job type and set it back properties.jobType.rejectChange(); setJobTypeSpinner(properties.jobType.get()); } } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String newText = null; switch(parent.getId()) { case R.id.job_search_type: newText = typeSpinner.getSelectedItem().toString(); JobSearchProperties.JOBTYPE newType = JobSearchProperties.JOBTYPE.fromString(newText); properties.jobType.set(newType); if (properties.jobType.hasChanged()) { listener.onJobTypeChange(typeSpinner, newType); // Depending on which type is set, it will affect the checkboxes switch(newType) { case GRADUATING: case ALUMNI: case SUMMER: juniorChkbx.setChecked(false); intermediateChkbx.setChecked(false); seniorChkbx.setChecked(false); if (newType == JobSearchProperties.JOBTYPE.SUMMER) { bachelorChkbx.setChecked(false); mastersChkbx.setChecked(false); phdChkbx.setChecked(false); } break; default: break; } } break; case R.id.job_search_location: newText = position == 0 ? "" : locationSpinner.getSelectedItem().toString(); properties.location.set(newText); break; case R.id.job_search_disciples1: newText = position == 0 ? "" : disciplines1Spinner.getSelectedItem().toString(); properties.disciplines1.set(newText); break; case R.id.job_search_disciples2: newText = position == 0 ? "" : disciplines2Spinner.getSelectedItem().toString(); properties.disciplines2.set(newText); break; case R.id.job_search_disciples3: newText = position == 0 ? "" : disciplines3Spinner.getSelectedItem().toString(); properties.disciplines3.set(newText); break; case R.id.job_search_term: newText = termSpinner.getSelectedItem().toString(); newText = newText.substring(newText.lastIndexOf("(") + 1, newText.lastIndexOf(")")); properties.term.set(newText); break; case R.id.job_search_filter: newText = filterSpinner.getSelectedItem().toString(); JobSearchProperties.FILTER newFilter = JobSearchProperties.FILTER.fromString(newText); properties.filter.set(newFilter); break; } } @Override public void onNothingSelected(AdapterView<?> parent) { } // Sets the search button to not close after clicking it @Override public void onShow(DialogInterface dialogInterface) { Button posButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); posButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { sendSearch(); } }); } public void sendSearch() { // Update the edittext, if changed they will be marked automatically properties.employer.set(employerText.getText().toString()); properties.title.set(jobTitleText.getText().toString()); // Update the checkboxes properties.levelJunior.set(juniorChkbx.isChecked()); properties.levelIntermediate.set(intermediateChkbx.isChecked()); properties.levelSenior.set(seniorChkbx.isChecked()); properties.levelBachelors.set(bachelorChkbx.isChecked()); properties.levelMasters.set(mastersChkbx.isChecked()); properties.levelPhD.set(phdChkbx.isChecked()); listener.onSearch(properties); } public static String stringifyTerm(Calendar date) { int month = date.get(Calendar.MONTH); int year = date.get(Calendar.YEAR); int termType = (int)Math.floor(month / 4) * 4 + 1; String term = Integer.toString(year - 1000).substring(0, 1); // Get first digit of year subtract 1 term += Integer.toString(year).substring(2); // Get 3rd digit of the year term += Integer.toString(termType); return term; } public static String readableTerm(Calendar date) { String term = stringifyTerm(date); char termType = term.charAt(3); switch(termType) { case '5': return "Spring " + date.get(Calendar.YEAR) + "\t(" + term + ")"; case '1': return "Winter " + date.get(Calendar.YEAR) + "\t(" + term + ")"; case '9': return "Fall " + date.get(Calendar.YEAR) + "\t(" + term + ")"; default: throw new JbmnplsParsingException("Not possible to get this term code."); } } public static Calendar getTimeFromTerm(String term) { Calendar then = Calendar.getInstance(); try { String year = Integer.toString(Integer.parseInt(term.substring(0, 1)) + 1) + '0'; year += term.substring(1, 3); then.setTime(sdf.parse(year)); char termType = term.charAt(3); switch(termType) { case '5': then.set(Calendar.MONTH, Calendar.MAY); break; case '1': then.set(Calendar.MONTH, Calendar.JANUARY); break; case '9': then.set(Calendar.MONTH, Calendar.SEPTEMBER); break; default: throw new JbmnplsParsingException("Not possible to get this term code."); } } catch (ParseException e) { throw new JbmnplsParsingException("Invalid term code, cannot parse"); } return then; } private void populateTermSpinner(String term) { Calendar then; if (term.equals("")) { then = Calendar.getInstance(); then.add(Calendar.MONTH, 4); } else { then = getTimeFromTerm(term); } // Get the last two terms and the next two terms long original = then.getTimeInMillis(); ArrayList<String> termList = new ArrayList<String>(); int currentIndex = -1; then.add(Calendar.MONTH, -8); // 2 terms ago for (int i = 0; i < 5; i++) { if (then.getTimeInMillis() == original) { currentIndex = i; } termList.add(readableTerm(then)); then.add(Calendar.MONTH, 4); } // Attach the values to the spinner ArrayAdapter<String> adapter = new ArrayAdapter<String>(ctx, android.R.layout.simple_spinner_item, termList); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); termSpinner.setAdapter(adapter); termSpinner.setSelection(currentIndex); } public interface OnJobSearchListener { public void onJobTypeChange(Spinner spinner, JobSearchProperties.JOBTYPE type); public void onSearch(JobSearchProperties properties); public void onCancel(); } }