package com.cradle.iitc_mobile; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.Comparator; public class IITC_MapSettings implements OnItemSelectedListener, OnItemClickListener, OnItemLongClickListener { private class HighlighterComparator implements Comparator { @Override public int compare(String lhs, String rhs) { // Move "No Highlights" on top. Sort the rest alphabetically if (lhs.equals("No Highlights")) return -1000; else if (rhs.equals("No Highlights")) return 1000; else return lhs.compareTo(rhs); } } private class Layer { boolean active; int id; String name; @Override public String toString() { return name; } } private class LayerAdapter extends ArrayAdapter { public LayerAdapter(int resource) { super(mIitc, resource); } @Override public View getView(int position, View convertView, ViewGroup parent) { Layer item = getItem(position); View view = (TextView) super.getView(position, convertView, parent); if (view instanceof CheckedTextView) ((CheckedTextView) view).setChecked(item.active); return view; } } private IITC_Mobile mIitc; private ArrayAdapter mHighlighters; private ArrayAdapter mBaseLayers; private ArrayAdapter mOverlayLayers; private Spinner mSpinnerBaseMap; private Spinner mSpinnerHighlighter; private ListView mListViewOverlayLayers; private String mActiveHighlighter; private int mActiveLayer; private class HighlighterAdapter extends ArrayAdapter { private HighlighterComparator mComparator = new HighlighterComparator(); private HighlighterAdapter(int resource) { super(mIitc, resource); clear(); } @Override public void add(String object) { super.remove(object); // to avoid duplicates super.add(object); super.sort(mComparator); } @Override public void clear() { super.clear(); add("No Highlights");// Probably must be the same as window._no_highlighter } } public IITC_MapSettings(IITC_Mobile activity) { mIitc = activity; mHighlighters = new HighlighterAdapter(R.layout.list_item_narrow); mBaseLayers = new LayerAdapter(R.layout.list_item_narrow); mOverlayLayers = new LayerAdapter(android.R.layout.simple_list_item_multiple_choice); mHighlighters.setDropDownViewResource(R.layout.list_item_selectable); mBaseLayers.setDropDownViewResource(R.layout.list_item_selectable); LayoutInflater inflater = (LayoutInflater) mIitc.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View header = inflater.inflate(R.layout.map_options_header, null); mSpinnerHighlighter = (Spinner) header.findViewById(R.id.spinnerHighlighter); mSpinnerBaseMap = (Spinner) header.findViewById(R.id.spinnerBaseLayer); mListViewOverlayLayers = (ListView) mIitc.findViewById(R.id.right_drawer); mListViewOverlayLayers.addHeaderView(header); mSpinnerHighlighter.setAdapter(mHighlighters); mSpinnerBaseMap.setAdapter(mBaseLayers); mListViewOverlayLayers.setAdapter(mOverlayLayers); mSpinnerHighlighter.setOnItemSelectedListener(this); mSpinnerBaseMap.setOnItemSelectedListener(this); mListViewOverlayLayers.setOnItemClickListener(this); mListViewOverlayLayers.setOnItemLongClickListener(this); } public void updateLayers() { mIitc.getWebView().loadUrl("javascript: window.layerChooser.getLayers()"); } public void addPortalHighlighter(String name) { mHighlighters.add(name); if (name.equals(mActiveHighlighter)) setActiveHighlighter(name); } public void setActiveHighlighter(String name) { mActiveHighlighter = name; int position = mHighlighters.getPosition(mActiveHighlighter); if (position >= 0 && position < mHighlighters.getCount()) mSpinnerHighlighter.setSelection(position); } public void setLayers(String base_layer, String overlay_layer) { /* * the layer strings have a form like: * [{"layerId":27,"name":"MapQuest OSM","active":true}, * {"layerId":28,"name":"Default Ingress Map","active":false}] * Put it in a JSONArray and parse it */ JSONArray base_layers = null; JSONArray overlay_layers = null; try { base_layers = new JSONArray(base_layer); overlay_layers = new JSONArray(overlay_layer); } catch (JSONException e) { e.printStackTrace(); return; } mActiveLayer = 0; mBaseLayers.setNotifyOnChange(false); mBaseLayers.clear(); for (int i = 0; i < base_layers.length(); i++) { try { JSONObject layerObj = base_layers.getJSONObject(i); Layer layer = new Layer(); layer.id = layerObj.getInt("layerId"); layer.name = layerObj.getString("name"); layer.active = layerObj.getBoolean("active"); if (layer.active) // getCount() will be the index of the layer we are about to add mActiveLayer = mBaseLayers.getCount(); mBaseLayers.add(layer); } catch (JSONException e) { e.printStackTrace(); continue; } } mBaseLayers.notifyDataSetChanged(); mSpinnerBaseMap.setSelection(mActiveLayer); mOverlayLayers.setNotifyOnChange(false); mOverlayLayers.clear(); for (int i = 0; i < overlay_layers.length(); i++) { try { JSONObject layerObj = overlay_layers.getJSONObject(i); Layer layer = new Layer(); layer.id = layerObj.getInt("layerId"); layer.name = layerObj.getString("name"); layer.active = layerObj.getBoolean("active"); mOverlayLayers.add(layer); } catch (JSONException e) { e.printStackTrace(); continue; } } mOverlayLayers.notifyDataSetChanged(); } private void updateLayer(Layer layer) { mIitc.getWebView().loadUrl( "javascript: window.layerChooser.showLayer(" + layer.id + "," + layer.active + ");"); } @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { if (parent.equals(mSpinnerHighlighter)) { String name = mHighlighters.getItem(position); mIitc.getWebView().loadUrl("javascript: window.changePortalHighlights('" + name + "')"); } else if (parent.equals(mSpinnerBaseMap)) { mBaseLayers.getItem(mActiveLayer).active = false; // set old layer to hidden, but no need to really hide Layer layer = mBaseLayers.getItem(position); layer.active = true; updateLayer(layer); } } @Override public void onNothingSelected(AdapterView parent) { // ignore } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { position--; // The ListView header counts as an item as well. Layer item = mOverlayLayers.getItem(position); item.active = !item.active; updateLayer(item); mOverlayLayers.notifyDataSetChanged(); } @Override public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { position--; // The ListView header counts as an item as well. boolean active = !mOverlayLayers.getItem(position).active; for (int i = 0; i < mOverlayLayers.getCount(); i++) { Layer item = mOverlayLayers.getItem(i); if (item.name.contains("DEBUG")) continue; if (active == item.active) continue; // no need to set same value again item.active = active; updateLayer(item); } mOverlayLayers.notifyDataSetChanged(); return true; } }