package com.ushahidi.android.app.checkin;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.ushahidi.android.app.R;
/**
* Created by IntelliJ IDEA. User: Ahmed Date: 2/17/11 Time: 2:45 PM To change
* this template use File | Settings | File Templates.
*/
public class CheckinItemizedOverlay<Item> extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private MapView mapView;
private CheckinBalloonOverlayView balloonView;
private CheckinMap iMap;
private List<Checkin> mCheckins;
//private Bundle extras;
private int viewOffset;
private View clickRegion;
private MapController mc = null;
public CheckinItemizedOverlay(Drawable drawable) {
super(boundCenter(drawable));
}
public CheckinItemizedOverlay(Drawable marker, MapView mapView, CheckinMap iMap,
List<Checkin> checkins, Bundle extras) {
super(marker);
this.mapView = mapView;
this.viewOffset = 32;
this.iMap = iMap;
this.mc = mapView.getController();
this.mCheckins = checkins;
//this.extras = extras;
}
/**
* Set the horizontal distance between the marker and the bottom of the
* information balloon. The default is 0 which works well for center bounded
* markers. If your marker is center-bottom bounded, call this before adding
* overlay items to ensure the balloon hovers exactly above the marker.
*
* @param pixels - The padding between the center point and the bottom of
* the information balloon.
*/
public void setBalloonBottomOffset(int pixels) {
viewOffset = pixels;
}
/**
* Override this method to handle a "tap" on a balloon. By default, does
* nothing and returns false.
*
* @param index - The index of the item whose balloon is tapped.
* @return true if you handled the tap, otherwise false.
*/
protected boolean onBalloonTap(int index) {
return false;
}
/*
* (non-Javadoc)
* @see com.google.android.maps.ItemizedOverlay#onTap(int)
*/
@Override
protected final boolean onTap(int index) {
boolean isRecycled;
final int thisIndex;
GeoPoint point;
thisIndex = index;
point = createItem(index).getPoint();
if (balloonView == null) {
balloonView = new CheckinBalloonOverlayView(this.iMap, mapView.getContext(),
viewOffset, mCheckins, thisIndex);
clickRegion = balloonView.findViewById(R.id.balloon_inner_layout);
isRecycled = false;
} else {
isRecycled = true;
}
balloonView.setVisibility(View.GONE);
balloonView.setData(createItem(index),index);
MapView.LayoutParams params = new MapView.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, point, MapView.LayoutParams.BOTTOM_CENTER);
params.mode = MapView.LayoutParams.MODE_MAP;
setBalloonTouchListener(thisIndex);
balloonView.setVisibility(View.VISIBLE);
if (isRecycled) {
balloonView.setLayoutParams(params);
} else {
mapView.addView(balloonView, params);
}
mc.animateTo(point);
return true;
}
/**
* Sets the onTouchListener for the balloon being displayed, calling the
* overridden onBalloonTap if implemented.
*
* @param thisIndex - The index of the item whose balloon is tapped.
*/
private void setBalloonTouchListener(final int thisIndex) {
try {
@SuppressWarnings("unused")
Method m = this.getClass().getDeclaredMethod("onBalloonTap", int.class);
clickRegion.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
View l = ((View)v.getParent()).findViewById(R.id.balloon_main_layout);
Drawable d = l.getBackground();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int[] states = {
android.R.attr.state_pressed
};
if (d.setState(states)) {
d.invalidateSelf();
}
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
int newStates[] = {};
if (d.setState(newStates)) {
d.invalidateSelf();
}
// call overridden method
onBalloonTap(thisIndex);
return true;
} else {
return false;
}
}
});
} catch (SecurityException e) {
return;
} catch (NoSuchMethodException e) {
// method not overridden - do nothing
return;
}
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
}