package com.example.providers;

import android.content.Context;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

public class ImagePagerAdapter extends FragmentStatePagerAdapter {

  private final LayoutInflater inflater;
  private final Context context;
  private final int targetWidth;
  private final int targetHeight;

  private Cursor cursor;

  public ImagePagerAdapter(Context _context, FragmentManager _fm) {
    this(_context, _fm, null);
  }

  public ImagePagerAdapter(Context _context, FragmentManager _fm, Cursor _cursor) {
    super(_fm);
    this.context = _context;
    this.cursor = _cursor;
    inflater = LayoutInflater.from(_context);
    Display display = ((WindowManager) context
        .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    Point displaySize = new Point();
    display.getSize(displaySize);
    targetWidth = displaySize.x;
    targetHeight = displaySize.y;
  }

  @Override
  public int getCount() {
    return (cursor == null) ? 0 : cursor.getCount();
  }

  @Override
  public Fragment getItem(int position) {
    Fragment fragment = new ImagePagerActivity.ImageFragment();
    cursor.moveToPosition(position);
    View view = newView();
    bindView(view, context, cursor);
    ((ImagePagerActivity.ImageFragment) fragment).putView(view);
    return fragment;
  }

  public void swapCursor(Cursor c) {
    if (cursor != c) {
      if (cursor != null) {
        cursor.close();
      }
      this.cursor = c;
      notifyDataSetChanged();
    }
  }

  public Cursor getCursor() {
    return cursor;
  }

  public View newView() {
    final View view = inflater.inflate(R.layout.image_item, null);
    return view;
  }

  public void bindView(View view, Context context, Cursor cursor) {
    ViewHolder holder = (ViewHolder) view.getTag();
    if (holder == null) {
      holder = new ViewHolder();
      holder.nameCol = cursor
          .getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME);
      holder.dataCol = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
      holder.imageName = (TextView) (view.findViewById(R.id.imageName));
      holder.imageView = (ImageView) (view.findViewById(R.id.imageView));
      view.setTag(holder);
    }
    holder.imageName.setText(cursor.getString(holder.nameCol));
    scaleAndLoadImage(context, cursor.getString(holder.dataCol),
        holder.imageView);
  }

  private static final class ViewHolder {
    public TextView imageName;
    public ImageView imageView;
    public int nameCol;
    public int dataCol;
  }

  private void scaleAndLoadImage(Context context, String fileName,
      ImageView imageView) {
    // Loading more than a few hi-def images will cause crash with
    // OutOfMemoryError - bitmap size exceeds VM budget

    // Decode without building bitmap to determine image size
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(fileName, options);
    final int actualWidth = options.outWidth;
    final int actualHeight = options.outHeight;
    final int widthRatio = Math
        .round((float) actualWidth / (float) targetWidth);
    final int heightRatio = Math.round((float) actualHeight
        / (float) targetHeight);

    // Choose image sample size based on the smaller of the ratios
    options.inSampleSize = (heightRatio < widthRatio ? heightRatio : widthRatio);
    Log.v("Providers", "Actual: " + actualWidth + "x" + actualHeight
        + " imageView: " + targetWidth + "x" + targetHeight + "  Ratios: "
        + widthRatio + ", " + heightRatio);
    options.inJustDecodeBounds = false;
    imageView.setImageBitmap(BitmapFactory.decodeFile(fileName, options));
  }

}