@@ -1,17 +1,16 @@
package com.example.aaron.metandroid;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -37,226 +36,249 @@

public class Map extends Activity {

private Float density;
private MyPlayer myPlayer;
private PhotoViewAttacher largeMapView;
private ListView galleriesView;
private GalleryAdapter galleryAdapter;
private TextView galleryHeader;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);

final MyPlayer myPlayer = new MyPlayer(
density = getResources().getDisplayMetrics().density;

myPlayer = new MyPlayer(
(SeekBar) findViewById(R.id.seek),
(Button) findViewById(R.id.play),
(TextView) findViewById(R.id.time),
(TextView) findViewById(R.id.audioTitle)
);

final PhotoViewAttacher largeMapView = new PhotoViewAttacher((DebugMapView) findViewById(R.id.largeMap));
largeMapView = new PhotoViewAttacher((DebugMapView) findViewById(R.id.largeMap));
largeMapView.setMaximumScale(7.0f);

final ListView listView = (ListView) findViewById(R.id.listView);
final Float density = getResources().getDisplayMetrics().density;

final Activity activity = this;
final ArrayAdapter<StopModel> listAdapter = new ArrayAdapter<StopModel>(this, android.R.layout.simple_list_item_1) {
class GalleryHolder {
private final TextView titleView;
private final ImageView imageView;
private final ImageView mapView;
private final ArrayList<TextView> audioTextViews = new ArrayList<>(6);

public GalleryHolder(TextView titleView, ImageView mapView, ImageView imageView, TextView audio0, TextView audio1, TextView audio2, TextView audio3, TextView audio4, TextView audio5) {
this.titleView = titleView;
this.mapView = mapView;
this.imageView = imageView;
this.audioTextViews.add(audio0);
this.audioTextViews.add(audio1);
this.audioTextViews.add(audio2);
this.audioTextViews.add(audio3);
this.audioTextViews.add(audio4);
this.audioTextViews.add(audio5);
}

public TextView getAudio(int i) {
return audioTextViews.get(i);
}
}
galleriesView = (ListView) findViewById(R.id.listView);
galleryAdapter = new GalleryAdapter(this, android.R.layout.simple_list_item_1);
galleriesView.setAdapter(galleryAdapter);

@Override
public boolean isEnabled(int position) {
return false;
}
galleryHeader = (TextView) findViewById(R.id.galleryHeader);

@Override
public View getView(int position, View convertView, ViewGroup parent) {
StopModel model = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.gallery, parent, false);
GalleryHolder holder = new GalleryHolder(
(TextView) convertView.findViewById(R.id.title),
(ImageView) convertView.findViewById(R.id.mapView),
(ImageView) convertView.findViewById(R.id.objectImage),
(TextView) convertView.findViewById(R.id.audio0),
(TextView) convertView.findViewById(R.id.audio1),
(TextView) convertView.findViewById(R.id.audio2),
(TextView) convertView.findViewById(R.id.audio3),
(TextView) convertView.findViewById(R.id.audio4),
(TextView) convertView.findViewById(R.id.audio5)
);
convertView.setTag(holder);
}
final GalleryHolder holder = (GalleryHolder) convertView.getTag();
holder.titleView.setText(model.getTitle());
holder.imageView.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT;
// scroll to center of gallery
// GalleryViewRect rect = MyApplication.galleryRectById.get(model.getGalleryId());
// Rect r = new Rect();
// rect.getTransformed().round(r);
// holder.mapView.requestRectangleOnScreen(r);
holder.mapView.scrollTo(500, 500);
holder.mapView.invalidate();

Glide.with(activity).load(model.getImageURL()).transform(new BitmapTransformation(activity) {
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Matrix m = new Matrix();
Float scale = (50.0f * density) / toTransform.getWidth();
//holder.imageView.getLayoutParams().height = new Float(toTransform.getHeight() * scale).intValue();
m.setScale(scale, scale);
if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
return toTransform;
}
return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), m, true);
}
largeMapView.setOnViewTapListener(new OnMapTap());
}

@Override
public String getId() {
return "scaled123";
}
}).diskCacheStrategy(DiskCacheStrategy.RESULT).into(holder.imageView);

int mediaSize = model.getMedias().size();
for (int i = 0; i < 6; i++) {
TextView audioTitle = holder.getAudio(i);
audioTitle.setOnClickListener(null);
if (i < mediaSize) {
audioTitle.setVisibility(View.VISIBLE);
final MediaModel media = model.getMedias().get(i);
audioTitle.setText(media.getTitle());
audioTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
myPlayer.play(media.getUri(), media.getTitle());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
} else {
audioTitle.setVisibility(View.GONE);
}
}
private class OnMapTap implements PhotoViewAttacher.OnViewTapListener {
@Override
public void onViewTap(View view, float v, float v1) {
Matrix matrix = new Matrix();
largeMapView.getDisplayMatrix().invert(matrix);
float[] coordinates = new float[]{v, v1};
matrix.mapPoints(coordinates);
matrix.postScale(largeMapView.getScale(), largeMapView.getScale());
matrix.postTranslate(v, v1);
float realX = coordinates[0] / density;
float realY = coordinates[1] / density;
Log.e("tag", realX + " " + realY);

return convertView;
}
};
listView.setAdapter(listAdapter);

final TextView galleryHeader = (TextView) findViewById(R.id.galleryHeader);

largeMapView.setOnViewTapListener(new PhotoViewAttacher.OnViewTapListener() {
@Override
public void onViewTap(View view, float v, float v1) {
Matrix matrix = new Matrix();
largeMapView.getDisplayMatrix().invert(matrix);
float[] coordinates = new float[]{v, v1};
matrix.mapPoints(coordinates);
matrix.postScale(largeMapView.getScale(), largeMapView.getScale());
matrix.postTranslate(v, v1);
float realX = coordinates[0] / density;
float realY = coordinates[1] / density;
Log.e("tag", realX + " " + realY);


listAdapter.clear();
for (GalleryViewRect rect : MyApplication.galleryRectById.values()) {
if (rect.getOriginal().contains(realX, realY)) {
galleryHeader.setText("Gallery " + rect.getId());
SQLiteDatabase db = new FeedReaderDbHelper(getApplicationContext()).getReadableDatabase();
try (Cursor c = db.rawQuery(
"SELECT s.objectId, s.title as objectTitle, image, m.title as audioTitle, m.uri as audio, m.stop, m.position " +
"FROM processed_stop s " +
"INNER JOIN processed_media m ON (s.id = m.stop) " +
"WHERE gallery = " + rect.getId() + " " +
"AND m.uri IS NOT NULL " +
"ORDER BY m.stop, m.position ", null)
) {
HashMap<Integer, ArrayList<QueryModel>> modelsByObjectId = new HashMap<>();
while ((c.moveToNext())) {
int objectId = c.getInt(c.getColumnIndexOrThrow("objectId"));
String title = c.getString(c.getColumnIndexOrThrow("objectTitle"));
String image = c.getString(c.getColumnIndexOrThrow("image"));
String audioTitle = c.getString(c.getColumnIndex("audioTitle"));
String audio = c.getString(c.getColumnIndex("audio"));
int stop = c.getInt(c.getColumnIndex("stop"));
int position = c.getInt(c.getColumnIndex("position"));
QueryModel model = new QueryModel(title, image, audioTitle, audio, stop, position);
if (!modelsByObjectId.containsKey(objectId)) {
modelsByObjectId.put(objectId, new ArrayList<QueryModel>());
}
ArrayList<QueryModel> models = modelsByObjectId.get(objectId);
boolean hasAudio = false;
for (QueryModel q : models) {
if (q.getMediaURL().equals(audio)) {
hasAudio = true;
}
}
if (!hasAudio)
models.add(model);

galleryAdapter.clear();
for (GalleryViewRect rect : MyApplication.galleryRectById.values()) {
if (rect.getOriginal().contains(realX, realY)) {
galleryHeader.setText("Gallery " + rect.getId());
SQLiteDatabase db = new FeedReaderDbHelper(getApplicationContext()).getReadableDatabase();
try (Cursor c = db.rawQuery(
"SELECT s.objectId, s.title as objectTitle, image, m.title as audioTitle, m.uri as audio, m.stop, m.position " +
"FROM processed_stop s " +
"INNER JOIN processed_media m ON (s.id = m.stop) " +
"WHERE gallery = " + rect.getId() + " " +
"AND m.uri IS NOT NULL " +
"ORDER BY m.stop, m.position ", null)
) {
HashMap<Integer, ArrayList<QueryModel>> modelsByObjectId = new HashMap<>();
while ((c.moveToNext())) {
int objectId = c.getInt(c.getColumnIndexOrThrow("objectId"));
String title = c.getString(c.getColumnIndexOrThrow("objectTitle"));
String image = c.getString(c.getColumnIndexOrThrow("image"));
String audioTitle = c.getString(c.getColumnIndex("audioTitle"));
String audio = c.getString(c.getColumnIndex("audio"));
int stop = c.getInt(c.getColumnIndex("stop"));
int position = c.getInt(c.getColumnIndex("position"));
QueryModel model = new QueryModel(title, image, audioTitle, audio, stop, position);
if (!modelsByObjectId.containsKey(objectId)) {
modelsByObjectId.put(objectId, new ArrayList<QueryModel>());
}
ArrayList<StopModel> stopModels = new ArrayList<>();
for (ArrayList<QueryModel> qs : modelsByObjectId.values()) {
StopModel stopModel = new StopModel(rect.getId(), qs.get(0).getTitle(), qs.get(0).getImageURL());
for (QueryModel q : qs) {
stopModel.addMedia(new MediaModel(q.getMediaTitle(), q.getMediaURL(), q.getStopId()));
ArrayList<QueryModel> models = modelsByObjectId.get(objectId);
boolean hasAudio = false;
for (QueryModel q : models) {
if (q.getMediaURL().equals(audio)) {
hasAudio = true;
}
stopModels.add(stopModel);
}
Collections.sort(stopModels);
listAdapter.addAll(stopModels);
listView.setSelection(0);
if (!hasAudio)
models.add(model);

}
ArrayList<StopModel> stopModels = new ArrayList<>();
for (ArrayList<QueryModel> qs : modelsByObjectId.values()) {
StopModel stopModel = new StopModel(rect.getId(), qs.get(0).getTitle(), qs.get(0).getImageURL());
for (QueryModel q : qs) {
stopModel.addMedia(new MediaModel(q.getMediaTitle(), q.getMediaURL(), q.getStopId()));
}
stopModels.add(stopModel);
}
Collections.sort(stopModels);
galleryAdapter.addAll(stopModels);
galleriesView.setSelection(0);
}
}
}
});
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_map, menu);
return true;
}
private class GalleryAdapter extends ArrayAdapter<StopModel> {

@Override
public boolean onTouchEvent(MotionEvent ev) {
//scaleGestureDetector.onTouchEvent(ev);
return true;
}
public GalleryAdapter(Context context, int resource) {
super(context, resource);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
class GalleryHolder {
private final TextView titleView;
private final ImageView imageView;
private final ImageView mapView;
private final ArrayList<TextView> audioTextViews = new ArrayList<>(6);
private final ArrayList<View> audioDividers = new ArrayList<>(6);

public GalleryHolder(TextView titleView, ImageView mapView, ImageView imageView,
TextView audio0, TextView audio1, TextView audio2, TextView audio3,
TextView audio4, TextView audio5, View divider0, View divider1, View divider2, View divider3, View divider4) {
this.titleView = titleView;
this.mapView = mapView;
this.imageView = imageView;
this.audioTextViews.add(audio0);
this.audioTextViews.add(audio1);
this.audioTextViews.add(audio2);
this.audioTextViews.add(audio3);
this.audioTextViews.add(audio4);
this.audioTextViews.add(audio5);
this.audioDividers.add(divider0);
this.audioDividers.add(divider1);
this.audioDividers.add(divider2);
this.audioDividers.add(divider3);
this.audioDividers.add(divider4);
}

public TextView getAudio(int i) {
return audioTextViews.get(i);
}

public View getDivider(int i) {
return audioDividers.get(i);
}
}

@Override
public boolean isEnabled(int position) {
return false;
}

return super.onOptionsItemSelected(item);
@Override
public View getView(int position, View convertView, ViewGroup parent) {
StopModel model = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.gallery, parent, false);
GalleryHolder holder = new GalleryHolder(
(TextView) convertView.findViewById(R.id.title),
(ImageView) convertView.findViewById(R.id.mapView),
(ImageView) convertView.findViewById(R.id.objectImage),
(TextView) convertView.findViewById(R.id.audio0),
(TextView) convertView.findViewById(R.id.audio1),
(TextView) convertView.findViewById(R.id.audio2),
(TextView) convertView.findViewById(R.id.audio3),
(TextView) convertView.findViewById(R.id.audio4),
(TextView) convertView.findViewById(R.id.audio5),
(View) convertView.findViewById(R.id.audioDivider0),
(View) convertView.findViewById(R.id.audioDivider1),
(View) convertView.findViewById(R.id.audioDivider2),
(View) convertView.findViewById(R.id.audioDivider3),
(View) convertView.findViewById(R.id.audioDivider4)
);
convertView.setTag(holder);
}
final GalleryHolder holder = (GalleryHolder) convertView.getTag();
holder.titleView.setText(model.getTitle());
holder.imageView.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT;
//scroll to center of gallery
GalleryViewRect rect = MyApplication.galleryRectById.get(model.getGalleryId());
// Matrix m = new Matrix();
// RectF drawableRect = new RectF(0, 0,
// 200,
// 200);
// m.setRectToRect(drawableRect, rect.getOriginal(), Matrix.ScaleToFit.FILL);
// holder.mapView.setImageMatrix(m);

// holder.mapView.getImageMatrix().mapRect(rect.getScaled());
// holder.mapView.requestRectangleOnScreen(r);
// holder.mapView.setScaleX(2.0f);
// holder.mapView.setScaleY(2.0f);
int scrollPadding = 0;
holder.mapView.scrollTo(
Math.max(0, Math.round(rect.getScaled().left - scrollPadding)),
Math.max(0, Math.round(rect.getScaled().top - scrollPadding))
);

holder.mapView.invalidate();

Glide.with(getContext()).load(model.getImageURL()).transform(new BitmapTransformation(getContext()) {
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Matrix m = new Matrix();
Float scale = (75.0f * density) / toTransform.getWidth();
//holder.imageView.getLayoutParams().height = new Float(toTransform.getHeight() * scale).intValue();
m.setScale(scale, scale);
if (toTransform.getWidth() == outWidth && toTransform.getHeight() == outHeight) {
return toTransform;
}
return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), m, true);
}

@Override
public String getId() {
return "scaled123";
}
}).diskCacheStrategy(DiskCacheStrategy.RESULT).into(holder.imageView);

int mediaSize = model.getMedias().size();
for (int i = 0; i < 6; i++) {
TextView audioTitle = holder.getAudio(i);
audioTitle.setOnClickListener(null);
audioTitle.setVisibility(View.GONE);
if (i < 5) {
holder.getDivider(i).setVisibility(View.GONE);
}
if (i < mediaSize) {
if (i > 0) {
holder.getDivider(i - 1).setVisibility(View.VISIBLE);
}
audioTitle.setVisibility(View.VISIBLE);
final MediaModel media = model.getMedias().get(i);
audioTitle.setText(media.getTitle());
audioTitle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
myPlayer.play(media.getUri(), media.getTitle());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}

return convertView;
}
}
}
@@ -48,16 +48,20 @@ public void onClick(View v) {
this.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int progressMinutes = progress / 60000;
int progressSeconds = progress % 60000 / 1000;

//Set this once in the beginning
int durationMinutes = mediaPlayer.getDuration() / 60000;
int durationSeconds = mediaPlayer.getDuration() % 60000 / 1000;

String formatted = String.format("%02d:%02d/%02d:%02d",
progressMinutes, progressSeconds, durationMinutes, durationSeconds);
timeView.setText(formatted);
if (isPrepared) {
int progressMinutes = progress / 60000;
int progressSeconds = progress % 60000 / 1000;

//Set this once in the beginning
int durationMinutes = mediaPlayer.getDuration() / 60000;
int durationSeconds = mediaPlayer.getDuration() % 60000 / 1000;

String formatted = String.format("%02d:%02d/%02d:%02d",
progressMinutes, progressSeconds, durationMinutes, durationSeconds);
timeView.setText(formatted);
} else {
seekBar.setProgress(0);
}
}

@Override
@@ -67,7 +71,9 @@ public void onStartTrackingTouch(SeekBar seekBar) {

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mediaPlayer.seekTo(seekBar.getProgress());
if (isPrepared) {
mediaPlayer.seekTo(seekBar.getProgress());
}
isSeekBarDragging = false;
}
});
@@ -29,6 +29,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select a Gallery"
android:background="@android:color/white"
android:textStyle="bold" />

<ListView
@@ -40,17 +41,17 @@
</LinearLayout>

<LinearLayout
android:background="@android:color/holo_blue_dark"
android:background="@color/lightGray"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight=".1"
android:gravity="center_horizontal"
android:orientation="horizontal">

<Button
android:id="@+id/play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="Play" />


@@ -62,8 +63,8 @@

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight=".5">
android:layout_height="wrap_content"
android:layout_weight="0">

<TextView
android:id="@+id/audioTitle"
@@ -83,8 +84,8 @@
<SeekBar
android:id="@+id/seek"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight=".5" />
android:layout_height="wrap_content"
style="@android:style/Widget.Holo.Light.SeekBar"/>

</LinearLayout>

@@ -19,8 +19,8 @@

<ImageView
android:id="@+id/objectImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_weight="0"
android:layout_marginEnd="5dp"
android:background="@android:color/darker_gray"
@@ -46,6 +46,7 @@
android:visibility="gone" />

<View
android:id="@+id/audioDivider0"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />
@@ -57,24 +58,48 @@
android:layout_height="wrap_content"
android:visibility="gone" />

<View
android:id="@+id/audioDivider1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />

<TextView
android:id="@+id/audio2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />

<View
android:id="@+id/audioDivider2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />

<TextView
android:id="@+id/audio3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />

<View
android:id="@+id/audioDivider3"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />

<TextView
android:id="@+id/audio4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />

<View
android:id="@+id/audioDivider4"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray" />

<TextView
android:id="@+id/audio5"
android:layout_width="wrap_content"
@@ -84,8 +109,8 @@

<ImageView
android:id="@+id/mapView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginStart="5dp"
android:layout_weight="0"
android:scaleType="matrix"
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="lightGray">#EEEEEE</color>
</resources>