/*
* Copyright 2011 Adi Sayoga.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adisayoga.earthquake.ui;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import com.adisayoga.earthquake.dto.EarthquakeDTO;
import com.adisayoga.earthquake.dto.EarthquakeTheme;
import com.adisayoga.earthquake.wrapper.DrawValues;
import com.adisayoga.earthquake.wrapper.Prefs;
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.MapView.LayoutParams;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
/**
* Overlay untuk titik gempa.
*
* @author Adi Sayoga
*/
public class EarthquakeOverlay extends ItemizedOverlay<OverlayItem> {
@SuppressWarnings("unused")
private static final String TAG = "EarthquakeOverlay";
private static final int TEXT_SIZE = 10;
private static final int PADDING = 2;
private final EarthquakeTheme theme;
private final Point point = new Point();
private final MapView mapView;
private final MapController controller;
private EarthquakeBalloonView balloonView = null;
private View clickRegion;
private int viewOffset = 0;
private final List<OverlayItem> items = new ArrayList<OverlayItem>();
private final List<EarthquakeDTO> quakes = new ArrayList<EarthquakeDTO>();
private Location location;
public EarthquakeOverlay(Drawable defaultMarker, MapView mapView, Location location) {
super(boundCenterBottom(defaultMarker));
this.mapView = mapView;
this.controller = mapView.getController();
this.location = location;
Prefs prefs = Prefs.getInstance(mapView.getContext());
theme = prefs.getTheme();
}
@Override
protected boolean onTap(int index) {
if (balloonView == null) {
balloonView = new EarthquakeBalloonView(mapView.getContext(), viewOffset);
mapView.addView(balloonView);
clickRegion = balloonView.getClickRegion();
clickRegion.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Toggle state
Drawable drawable = view.getBackground();
int[] states = drawable.getState();
if (states.length == 0) {
states = new int[] { android.R.attr.state_pressed };
} else {
states = new int[] {};
}
if (drawable.setState(states)) drawable.invalidateSelf();
return true;
}
return false;
}
});
}
// Reset state
Drawable drawable = clickRegion.getBackground();
drawable.setState(new int[] {});
drawable.invalidateSelf();
GeoPoint point = createItem(index).getPoint();
MapView.LayoutParams params = new MapView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams
.WRAP_CONTENT, point, LayoutParams.BOTTOM_CENTER);
params.mode = LayoutParams.MODE_MAP;
balloonView.setLayoutParams(params);
balloonView.setData(quakes.get(index), location);
List<Overlay> overlays = mapView.getOverlays();
if (overlays.size() > 1) hideOtherBalloons(overlays);
balloonView.setVisibility(View.VISIBLE);
controller.animateTo(point);
return true;
}
/**
* Sembunikan balloon view lainnya.
*
* @param overlays Daftar overlay
*/
private void hideOtherBalloons(List<Overlay> overlays) {
for (Overlay overlay : overlays) {
if (overlay instanceof EarthquakeOverlay && overlay != this) {
((EarthquakeOverlay) overlay).hideBalloon();
}
}
}
/**
* Sembunyikan balloon view ini.
*/
private void hideBalloon() {
if (balloonView != null) balloonView.setVisibility(View.GONE);
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (shadow) return;
for (int i = items.size() - 1; i >= 0; i--) {
drawQuake(canvas, mapView, quakes.get(i), theme);
}
}
/**
* Gambar titik gempa pada peta.
*
* @param canvas Canvas
* @param mapView MapView
* @param quake Data gempa
* @param theme Tema yang digunakan
*/
private void drawQuake(Canvas canvas, MapView mapView, EarthquakeDTO quake,
EarthquakeTheme theme) {
Projection projection = mapView.getProjection();
projection.toPixels(quake.getPoint(), point);
int height = mapView.getHeight();
int width = mapView.getWidth();
int scrollX = mapView.getScrollX();
int scrollY = mapView.getScrollY();
if (point.x < scrollX || point.x > scrollX + width) return;
if (point.y < scrollY || point.y > scrollY + height) return;
DrawValues.prepare(theme, TEXT_SIZE, quake.magnitude, quake.time);
int zoom = mapView.getZoomLevel();
int radius = (zoom >= 6) ? 4 : DrawValues.markRadius;
canvas.drawCircle(point.x, point.y, radius + 2, DrawValues.markGlowPaint);
canvas.drawCircle(point.x, point.y, radius + 1, DrawValues.markOutlinePaint);
canvas.drawCircle(point.x, point.y, radius, DrawValues.markPaint);
int dmgRadius = (int) projection.metersToEquatorPixels(DrawValues.dmgMeters);
if (dmgRadius > 3 * DrawValues.markRadius) {
canvas.drawCircle(point.x, point.y, dmgRadius, DrawValues.feelOutlinePaint);
canvas.drawCircle(point.x, point.y, dmgRadius, DrawValues.feelPaint);
}
if (zoom >= 6 && DrawValues.text != "") {
int x = point.x;
int y = point.y + radius + TEXT_SIZE + PADDING * 3;
canvas.drawText(DrawValues.text, x, y, DrawValues.textOutlinePaint);
canvas.drawText(DrawValues.text, x, y, DrawValues.textPaint);
}
}
/**
* Tambahkan overlay.
*
* @param overlay Overlay
*/
public void addOverlay(OverlayItem overlay) {
items.add(overlay);
populate();
}
/**
* Tambahkan data gempa.
*
* @param quake Data Gempa
*/
public void addQuake(EarthquakeDTO quake) {
quakes.add(quake);
OverlayItem overlay = new OverlayItem(quake.getPoint(), "", "");
items.add(overlay);
populate();
}
/**
* Hapus/kosongkan overlay dan data gempa
*/
public void clear() {
quakes.clear();
items.clear();
populate();
}
/**
* Set lokasi saat ini.
*
* @param location Lokasi
*/
public void setLocation(Location location) {
this.location = location;
}
/**
* Set offset bawah bolloon view.
*
* @param pixels Offset dalam pixels
*/
public void setBalloonBotomOffset(int pixels) {
this.viewOffset = pixels;
}
@Override
protected OverlayItem createItem(int i) {
return (items.size() > 0) ? items.get(i) : null;
}
@Override
public int size() {
return items.size();
}
}