// Path: tileview/src/main/java/com/moagrius/tileview/io/StreamProvider.java
// public interface StreamProvider {
//   InputStream getStream(int column, int row, Context context, Object data) throws Exception;
// }
// 
// Path: tileview/src/main/java/com/moagrius/tileview/io/StreamProviderAssets.java
// public class StreamProviderAssets implements StreamProvider {
//   @Override
//   public InputStream getStream(int column, int row, Context context, Object data) throws IOException {
//     String file = String.format(Locale.US, (String) data, column, row);
//     return context.getAssets().open(file);
//   }
// }
// 
// Path: tileview/src/main/java/com/moagrius/utils/Maths.java
// public class Maths {
// 
//   public static final double LOG_2 = Math.log(2);
// 
//   public static double log2(int n) {
//     return Math.log(n) / LOG_2;
//   }
// 
//   public static int roundWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return Math.round(value / step) * step;
//   }
// 
//   public static int roundUpWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return (int) Math.ceil(value / step) * step;
//   }
// 
//   public static int roundDownWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return (int) Math.floor(value / step) * step;
//   }
// 
//   public static float divideSafely(int dividend, float divisor) {
//     if (dividend == 0 || divisor == 0) {
//       return 0;
//     }
//     return dividend / divisor;
//   }
// 
// }


import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.moagrius.tileview.io.StreamProvider;
import com.moagrius.tileview.io.StreamProviderAssets;
import com.moagrius.utils.Maths;
import com.moagrius.widget.ScalingScrollView;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
  }

  private void updateViewportAndComputeTilesThrottled() {
    if (!mRenderThrottle.hasMessages(RENDER_THROTTLE_ID)) {
      mRenderThrottle.sendEmptyMessageDelayed(RENDER_THROTTLE_ID, RENDER_THROTTLE_INTERVAL);
    }
  }

  private void updateViewport() {
    mViewport.left = getScrollX();
    mViewport.top = getScrollY();
    mViewport.right = mViewport.left + getMeasuredWidth();
    mViewport.bottom = mViewport.top + getMeasuredHeight();
    updateScaledViewport();
  }

  private void updateScaledViewport() {
    // set unfilled to entire viewport, virtualized to scale
    float scale = getScale();
    mScaledViewport.set(
        (int) (mViewport.left / scale),
        (int) (mViewport.top / scale),
        (int) (mViewport.right / scale),
        (int) (mViewport.bottom / scale)
    );
  }

  public void populateTileGridFromViewport() {
    float tileSize = mTileSize * getScale() * mCurrentDetail.getSample();
    mGrid.rows.start = Maths.roundDownWithStep(mViewport.top / tileSize, mImageSample);
// Path: tileview/src/main/java/com/moagrius/tileview/io/StreamProvider.java
// public interface StreamProvider {
//   InputStream getStream(int column, int row, Context context, Object data) throws Exception;
// }
// 
// Path: tileview/src/main/java/com/moagrius/tileview/io/StreamProviderAssets.java
// public class StreamProviderAssets implements StreamProvider {
//   @Override
//   public InputStream getStream(int column, int row, Context context, Object data) throws IOException {
//     String file = String.format(Locale.US, (String) data, column, row);
//     return context.getAssets().open(file);
//   }
// }
// 
// Path: tileview/src/main/java/com/moagrius/utils/Maths.java
// public class Maths {
// 
//   public static final double LOG_2 = Math.log(2);
// 
//   public static double log2(int n) {
//     return Math.log(n) / LOG_2;
//   }
// 
//   public static int roundWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return Math.round(value / step) * step;
//   }
// 
//   public static int roundUpWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return (int) Math.ceil(value / step) * step;
//   }
// 
//   public static int roundDownWithStep(float value, int step) {
//     if (value == 0) {
//       return 0;
//     }
//     return (int) Math.floor(value / step) * step;
//   }
// 
//   public static float divideSafely(int dividend, float divisor) {
//     if (dividend == 0 || divisor == 0) {
//       return 0;
//     }
//     return dividend / divisor;
//   }
// 
// }


// Path: tileview/src/main/java/com/moagrius/tileview/TileView.java
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import com.moagrius.tileview.io.StreamProvider;
import com.moagrius.tileview.io.StreamProviderAssets;
import com.moagrius.utils.Maths;
import com.moagrius.widget.ScalingScrollView;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

  }

  private void updateViewportAndComputeTilesThrottled() {
    if (!mRenderThrottle.hasMessages(RENDER_THROTTLE_ID)) {
      mRenderThrottle.sendEmptyMessageDelayed(RENDER_THROTTLE_ID, RENDER_THROTTLE_INTERVAL);
    }
  }

  private void updateViewport() {
    mViewport.left = getScrollX();
    mViewport.top = getScrollY();
    mViewport.right = mViewport.left + getMeasuredWidth();
    mViewport.bottom = mViewport.top + getMeasuredHeight();
    updateScaledViewport();
  }

  private void updateScaledViewport() {
    // set unfilled to entire viewport, virtualized to scale
    float scale = getScale();
    mScaledViewport.set(
        (int) (mViewport.left / scale),
        (int) (mViewport.top / scale),
        (int) (mViewport.right / scale),
        (int) (mViewport.bottom / scale)
    );
  }

  public void populateTileGridFromViewport() {
    float tileSize = mTileSize * getScale() * mCurrentDetail.getSample();
    mGrid.rows.start = Maths.roundDownWithStep(mViewport.top / tileSize, mImageSample);
    mGrid.rows.end = Maths.roundUpWithStep(mViewport.bottom / tileSize, mImageSample);