package com.ijoomer.components.sobipro;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import pl.mg6.android.maps.extensions.ClusteringSettings;
import pl.mg6.android.maps.extensions.GoogleMap;
import pl.mg6.android.maps.extensions.GoogleMap.InfoWindowAdapter;
import pl.mg6.android.maps.extensions.GoogleMap.OnInfoWindowClickListener;
import pl.mg6.android.maps.extensions.Marker;
import pl.mg6.android.maps.extensions.SupportMapFragment;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.LatLngBounds.Builder;
import com.google.android.gms.maps.model.MarkerOptions;
import com.ijoomer.common.classes.IjoomerMapClusterIconProvider;
import com.ijoomer.common.classes.IjoomerSuperMaster;
import com.ijoomer.common.classes.IjoomerUtilities;
import com.ijoomer.customviews.IjoomerRatingBar;
import com.ijoomer.customviews.IjoomerTextView;
import com.ijoomer.library.sobipro.SobiproCategoriesDataProvider;
import com.ijoomer.src.R;
/**
* Activity class for SobiproMapActivity view
*
* @author tasol
*
*/
public class SobiproMapActivity extends SobiproMasterActivity implements SobiproTagHolder {
private HashMap<Marker, HashMap<String, String>> markerHashMap;
private GoogleMap googleMap;
private AQuery androidQuery;
private Bitmap bitmapScale;
private Bitmap bitmapCreate;
private static final double[] CLUSTER_SIZES = new double[] { 180, 160, 144, 120, 96 };
private MutableData[] dataArray = { new MutableData(6, new LatLng(-50, 0)), new MutableData(28, new LatLng(-52, 1)), new MutableData(496, new LatLng(-51, -2)), };
private Handler handler = new Handler();
private String IN_TABLE;
private ArrayList<String> IN_ENTRY_ID_ARRAY;
private SobiproCategoriesDataProvider dataProvider;
private int IN_POS;
private String IN_PAGELAYOUT;
private ArrayList<String> pageLayouts;
/**
* This method represented to manage updated data.
*/
private Runnable dataUpdater = new Runnable() {
@Override
public void run() {
for (MutableData data : dataArray) {
data.value = 7 + 3 * data.value;
}
onDataUpdate();
handler.postDelayed(this, 1000);
}
};
/**
* Overrides methods.
*/
@Override
protected void onResume() {
super.onResume();
handler.post(dataUpdater);
}
@Override
protected void onPause() {
super.onPause();
handler.removeCallbacks(dataUpdater);
}
@Override
public int setLayoutId() {
return R.layout.sobipro_map;
}
@Override
public void prepareViews() {
}
@Override
public void setActionListeners() {
}
@Override
public void initComponents() {
FragmentManager fm = getSupportFragmentManager();
SupportMapFragment f = (SupportMapFragment) fm.findFragmentById(R.id.maps);
googleMap = f.getExtendedMap();
markerHashMap = new HashMap<Marker, HashMap<String, String>>();
androidQuery = new AQuery(this);
dataProvider = new SobiproCategoriesDataProvider(SobiproMapActivity.this);
getIntentData();
pageLayouts = new ArrayList<String>(Arrays.asList(getResources().getStringArray(R.array.sobipro_pageLayout)));
androidQuery = new AQuery(SobiproMapActivity.this);
googleMap.setClustering(new ClusteringSettings().iconDataProvider(new IjoomerMapClusterIconProvider(getResources())).addMarkersDynamically(true));
googleMap.setInfoWindowAdapter(new InfoWindowAdapter() {
private TextView tv;
{
tv = new TextView(SobiproMapActivity.this);
tv.setTextColor(Color.BLACK);
}
private Collator collator = Collator.getInstance();
private Comparator<Marker> comparator = new Comparator<Marker>() {
public int compare(Marker lhs, Marker rhs) {
String leftTitle = lhs.getTitle();
String rightTitle = rhs.getTitle();
if (leftTitle == null && rightTitle == null) {
return 0;
}
if (leftTitle == null) {
return 1;
}
if (rightTitle == null) {
return -1;
}
return collator.compare(leftTitle, rightTitle);
}
};
@Override
public View getInfoContents(Marker marker) {
if (marker.isCluster()) {
List<Marker> markers = marker.getMarkers();
int i = 0;
String text = "";
while (i < 3 && markers.size() > 0) {
Marker m = Collections.min(markers, comparator);
String title = m.getTitle();
if (title == null) {
break;
}
text += title + "\n";
markers.remove(m);
i++;
}
if (text.length() == 0) {
text = "Markers with mutable data";
} else if (markers.size() > 0) {
text += "and " + markers.size() + " more...";
} else {
text = text.substring(0, text.length() - 1);
}
tv.setText(text);
return tv;
} else {
Object data = marker.getData();
if (data instanceof MutableData) {
MutableData mutableData = (MutableData) data;
tv.setText("Value: " + mutableData.value);
return tv;
}
}
return null;
}
@Override
public View getInfoWindow(Marker marker) {
try {
if (!marker.isCluster()) {
final HashMap<String, String> data = markerHashMap.get(marker);
View view;
switch (pageLayouts.indexOf(IN_PAGELAYOUT)) {
case 2:
view = LayoutInflater.from(SobiproMapActivity.this).inflate(R.layout.sobipro_restaurant_map_bubble, null);
IjoomerTextView txtRestaurantTitle = (IjoomerTextView) view.findViewById(R.id.txtTitle);
IjoomerRatingBar rtbRestaurantRating = (IjoomerRatingBar) view.findViewById(R.id.rtbRating);
IjoomerTextView txtRestaurantDistance = (IjoomerTextView) view.findViewById(R.id.txtDistance);
IjoomerTextView txtRestaurantPrice = (IjoomerTextView) view.findViewById(R.id.txtPrice);
IjoomerTextView txtRestaurantGoodFor = (IjoomerTextView) view.findViewById(R.id.txtGoodFor);
if (data.get("txtTitle") != null && data.get("txtTitle").length() > 0) {
txtRestaurantTitle.setText(data.get("txtTitle"));
txtRestaurantTitle.setVisibility(View.VISIBLE);
}
if (data.get("txtDistance") != null && data.get("txtDistance").length() > 0) {
txtRestaurantDistance.setText(IjoomerUtilities.convertDistance(data.get("txtDistance"), IjoomerUtilities.MILE, IjoomerUtilities.MILE) + " "
+ getString(R.string.sobipro_restaurant_miles_text));
txtRestaurantDistance.setVisibility(View.VISIBLE);
}
if (data.get("txtPrice") != null && data.get("txtPrice").length() > 0) {
txtRestaurantPrice.setText(data.get("txtPrice"));
txtRestaurantPrice.setVisibility(View.VISIBLE);
}
if (data.get("txtGoodFor") != null && data.get("txtGoodFor").length() > 0) {
txtRestaurantGoodFor.setText(data.get("txtGoodFor"));
txtRestaurantGoodFor.setVisibility(View.VISIBLE);
}
if (data.get("txtAvgRating") != null && data.get("txtAvgRating").length() > 0) {
rtbRestaurantRating.setFilledStarResourceId(R.drawable.sobipro_rating_transparent_entry_detail);
rtbRestaurantRating.setHalfFilledStarResourceId(R.drawable.sobipro_rating_transparent_half);
rtbRestaurantRating.setEmptyStarResourceId(R.drawable.sobipro_rating_empty_star);
rtbRestaurantRating.setStarBgColor(getResources().getColor(R.color.sobipro_green));
rtbRestaurantRating.setStarRating(Float.parseFloat(data.get("txtAvgRating")) / 2);
rtbRestaurantRating.setVisibility(View.VISIBLE);
}
return view;
default:
view = LayoutInflater.from(SobiproMapActivity.this).inflate(R.layout.sobipro_map_bubble, null);
LinearLayout lnrMapInfoWindow = (LinearLayout) view.findViewById(R.id.lnrMapInfoWindow);
IjoomerTextView txtTitle = (IjoomerTextView) view.findViewById(R.id.txtTitlePopup);
IjoomerRatingBar rtbRating = (IjoomerRatingBar) view.findViewById(R.id.rtbRatingPopup);
IjoomerTextView txtReview = (IjoomerTextView) view.findViewById(R.id.txtReviewPopup);
IjoomerTextView txtAddress = (IjoomerTextView) view.findViewById(R.id.txtAddressPopup);
IjoomerTextView txtDistance = (IjoomerTextView) view.findViewById(R.id.txtDistancePopup);
IjoomerTextView txtPrice = (IjoomerTextView) view.findViewById(R.id.txtPricePopup);
if (data.get("txtTitle") != null && data.get("txtTitle").length() > 0) {
txtTitle.setText(data.get("txtTitle"));
} else {
txtTitle.setVisibility(View.GONE);
}
if (data.get("txtAddress") != null && data.get("txtAddress").length() > 0) {
txtAddress.setText(data.get("txtAddress"));
} else {
txtAddress.setVisibility(View.GONE);
}
try {
if (data.get("txtDistance") != null && data.get("txtDistance").length() > 0) {
txtDistance.setText(data.get("txtDistance") + " " + SobiproMapActivity.this.getString(R.string.sobipro_miles_text));
} else {
txtDistance.setVisibility(View.GONE);
}
} catch (Exception e) {
e.printStackTrace();
}
if (data.get("txtReviewCount") != null && data.get("txtReviewCount").length() > 0) {
txtReview.setText(data.get("txtReviewCount") + " " + (SobiproMapActivity.this.getString(R.string.sobipro_detail_review_text)).toLowerCase());
} else {
txtReview.setVisibility(View.GONE);
}
if (data.get("txtPrice") != null && data.get("txtPrice").length() > 0) {
if (data.get("txtPrice") != null && data.get("txtPrice").length() > 0) {
int price = Integer.parseInt(data.get("txtPrice"));
String price_final = "";
String currency = data.get("txtCurrency");
for (int i = 0; i < price; i++)
price_final = price_final + currency;
txtPrice.setText(price_final);
} else {
txtPrice.setVisibility(View.GONE);
}
}
rtbRating.setFilledStarResourceId(R.drawable.sobipro_rating_transparent);
rtbRating.setHalfFilledStarResourceId(R.drawable.sobipro_rating_transparent_half);
rtbRating.setEmptyStarResourceId(R.drawable.sobipro_rating_empty_star);
rtbRating.setStarBgColor(SobiproMasterActivity.themes[IN_POS].getBgColor());
rtbRating.setStarRating(Float.parseFloat(data.get("txtAvgRating")) / 2);
lnrMapInfoWindow.setBackgroundColor(SobiproMasterActivity.themes[IN_POS].getBgColor());
return view;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
if (marker.isCluster()) {
List<Marker> markers = marker.getMarkers();
Builder builder = LatLngBounds.builder();
for (Marker m : markers) {
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, getResources().getDimensionPixelSize(R.dimen.padding)));
} else {
final HashMap<String, String> data = markerHashMap.get(marker);
goToEntryDetail(data);
marker.hideInfoWindow();
}
}
});
// MarkerGenerator.addMarkersInPoland(googleMap);
// MarkerGenerator.addMarkersInWorld(googleMap);
populateMap();
setUpClusteringViews();
}
/**
* Class methods.
*/
/**
* This method used to get intent data.
*/
private void getIntentData() {
try {
IN_ENTRY_ID_ARRAY = getIntent().getStringArrayListExtra("IN_ENTRY_ID_ARRAY");
IN_TABLE = getIntent().getStringExtra("IN_TABLE");
IN_POS = getIntent().getIntExtra("IN_POS", 0);
IN_PAGELAYOUT = getIntent().getStringExtra("IN_PAGELAYOUT");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* This method is used to go in Entry Detail after clicking InfoWindow on
* map.
*
* @param data
* represents entry detail data which is going to display.
*
*/
private void goToEntryDetail(HashMap<String, String> data) {
try {
ArrayList<String> ID_Array = new ArrayList<String>();
ID_Array.add(data.get(ID));
loadNew(SobiproEntryDetailActivity.class, SobiproMapActivity.this, false, "IN_ENTRY_ID_ARRAY", ID_Array, "IN_ENTRY_INDEX", 0, "IN_TABLE", IN_TABLE, "IN_POS", IN_POS,
"IN_PAGELAYOUT", IN_PAGELAYOUT);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* This method is used to update the Data.
*/
private void onDataUpdate() {
Marker m = googleMap.getMarkerShowingInfoWindow();
if (m != null && !m.isCluster() && m.getData() instanceof MutableData) {
m.showInfoWindow();
}
}
/**
* This method is used to set map clustering view.
*/
private void setUpClusteringViews() {
ClusteringSettings clusteringSettings = new ClusteringSettings();
clusteringSettings.addMarkersDynamically(true);
clusteringSettings.iconDataProvider(new IjoomerMapClusterIconProvider(getResources()));
double clusterSize = CLUSTER_SIZES[3];
clusteringSettings.clusterSize(clusterSize);
googleMap.setClustering(clusteringSettings);
}
/**
* This method is used to populate map view with clustering.
*/
private void populateMap() {
try {
if (IN_ENTRY_ID_ARRAY != null && IN_ENTRY_ID_ARRAY.size() > 0) {
for (int i = 0; i < IN_ENTRY_ID_ARRAY.size(); i++) {
ArrayList<HashMap<String, String>> hashMap = dataProvider.getEntriesFromCache(IN_TABLE, IN_ENTRY_ID_ARRAY.get(i));
try {
if (i == 0) {
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(Double.parseDouble(hashMap.get(i).get(LATITUDE)), Double.parseDouble(hashMap.get(i).get(
LONGITUDE)))));
}
final HashMap<String, String> entryData = new HashMap<String, String>();
switch (pageLayouts.indexOf(IN_PAGELAYOUT)) {
case 2:
try {
if (hashMap.get(0).get(LATITUDE) != null && hashMap.get(0).get(LATITUDE).toString().trim().length() > 0 && hashMap.get(0).get(LONGITUDE) != null
&& hashMap.get(0).get(LONGITUDE).toString().trim().length() > 0) {
for (HashMap<String, String> row : hashMap) {
if (row.get(LABELID).equalsIgnoreCase("field_good_for")) {
entryData.put("txtGoodFor", row.get(VALUE));
} else if (row.get(LABELID).equalsIgnoreCase("field_price")) {
int price = Integer.parseInt(row.get(VALUE));
String price_final = "";
String currency = row.get(UNIT);
if (price < 5) {
for (int j = 0; j < price; j++)
price_final = price_final + currency;
} else {
price_final = currency + currency + currency + currency + currency;
}
entryData.put("txtPrice", price_final);
}
}
entryData.put("txtDistance", hashMap.get(0).get("distance"));
entryData.put("txtTitle", hashMap.get(0).get(TITLE));
entryData.put(ID, hashMap.get(0).get(ID));
entryData.put("txtAvgRating", hashMap.get(0).get(AVERAGERATING));
if (hashMap.get(0).get("img_galleries") != null
&& ((IjoomerSuperMaster) SobiproMapActivity.this).getStringArray(hashMap.get(0).get("img_galleries"))[0] != null) {
entryData.put("imgLogo", ((IjoomerSuperMaster) SobiproMapActivity.this).getStringArray(hashMap.get(0).get("img_galleries"))[0]);
}
entryData.put(LATITUDE, hashMap.get(0).get("latitude"));
entryData.put(LONGITUDE, hashMap.get(0).get("longitude"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(Double.parseDouble(hashMap.get(i).get(LATITUDE)), Double.parseDouble(hashMap.get(
i).get(LONGITUDE)))));
placeMarker(entryData, R.drawable.sobipro_map_custom_marker_green);
}
} catch (Exception e) {
e.printStackTrace();
}
break;
default:
try {
if (hashMap.get(0).get(LATITUDE) != null && hashMap.get(0).get(LATITUDE).toString().trim().length() > 0 && hashMap.get(0).get(LONGITUDE) != null
&& hashMap.get(0).get(LONGITUDE).toString().trim().length() > 0) {
for (HashMap<String, String> row : hashMap) {
if (row.get(LABELID).equalsIgnoreCase(FIELDCOMPANYLOGO)) {
entryData.put("imgLogo", row.get(VALUE));
}
if (row.get(LABELID).equalsIgnoreCase(FIELDADDRESS)) {
entryData.put("txtAddress", row.get(VALUE));
}
if (row.get(LABELID).equalsIgnoreCase(FIELDPRICE)) {
entryData.put("txtPrice", row.get(VALUE));
entryData.put("txtCurrency", row.get(UNIT));
}
}
try {
double dist = distanceFrom(Float.parseFloat(getLatitude()), Float.parseFloat(getLongitude()),
Float.parseFloat(hashMap.get(0).get(LATITUDE)), Float.parseFloat(hashMap.get(0).get(LONGITUDE)));
entryData.put("txtDistance", dist + "");
} catch (Exception e) {
}
entryData.put("txtTitle", hashMap.get(0).get("title"));
entryData.put(ID, hashMap.get(0).get(ID));
entryData.put("txtAvgRating", hashMap.get(0).get(AVERAGERATING));
entryData.put("txtReviewCount", hashMap.get(0).get(TOTALREVIEWCOUNT));
entryData.put(LATITUDE, hashMap.get(0).get("latitude"));
entryData.put(LONGITUDE, hashMap.get(0).get("longitude"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(Double.parseDouble(hashMap.get(i).get(LATITUDE)), Double.parseDouble(hashMap.get(
i).get(LONGITUDE)))));
placeMarker(entryData, SobiproMasterActivity.themes[IN_POS].getMapMarkerDrawable());
}
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
googleMap.setMyLocationEnabled(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* This method is used to place markers at specific latitude and longitude
*
* @param entryData
* represented entry data which contains all the latitude and
* longitude which will displayed on map.
*/
private void placeMarker(final HashMap<String, String> entryData, final int FrameDrawable) {
try {
androidQuery.ajax(entryData.get("imgLogo"), Bitmap.class, 0, new AjaxCallback<Bitmap>() {
@Override
public void callback(String url, Bitmap object, AjaxStatus status) {
super.callback(url, object, status);
if (object == null) {
object = BitmapFactory.decodeResource(getResources(), R.drawable.sobipro_default_image);
}
markerHashMap.put(
googleMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromBitmap(combineImages(BitmapFactory.decodeResource(getResources(), FrameDrawable), object)))
.title(entryData.get("txtTitle"))
.position(new LatLng(Double.parseDouble(entryData.get(LATITUDE)), Double.parseDouble(entryData.get(LONGITUDE))))), entryData);
}
});
} catch (Exception e) {
markerHashMap.put(
googleMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromBitmap(combineImages(BitmapFactory.decodeResource(getResources(), FrameDrawable),
BitmapFactory.decodeResource(getResources(), R.drawable.sobipro_default_image)))).title(entryData.get("txtTitle"))
.position(new LatLng(Double.parseDouble(entryData.get(LATITUDE)), Double.parseDouble(entryData.get(LONGITUDE))))), entryData);
e.printStackTrace();
}
}
/**
* This method is used to combine frame image and entry image and make one
* image which will used to display as a marker.
*
* @param frame
* represented frame image.
* @param image
* represented entry image.
* @return
*/
public Bitmap combineImages(Bitmap frame, Bitmap image) {
bitmapScale = Bitmap.createScaledBitmap(image, convertSizeToDeviceDependent(45), convertSizeToDeviceDependent(40), true);
bitmapCreate = Bitmap.createBitmap(frame.getWidth(), frame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(bitmapCreate);
comboImage.drawBitmap(bitmapScale, convertSizeToDeviceDependent(7), convertSizeToDeviceDependent(7), null);
comboImage.drawBitmap(frame, 0, 0, null);
if (frame != null) {
try {
bitmapScale.recycle();
frame.recycle();
image.recycle();
bitmapScale = null;
frame = null;
image = null;
} catch (Throwable e) {
}
}
return bitmapCreate;
}
/**
* Custom class to handle Mutable Data.
*/
private static class MutableData {
private int value;
public MutableData(int value, LatLng position) {
this.value = value;
}
}
}