package ar.rulosoft.mimanganu.componentes.readers.paged;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import java.io.File;
import java.util.List;
import ar.rulosoft.mimanganu.R;
import ar.rulosoft.mimanganu.componentes.readers.Reader;
import it.sephiroth.android.library.TapListener;
import it.sephiroth.android.library.imagezoom.ImageViewTouch;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase;
import it.sephiroth.android.library.imagezoom.ImageViewTouchBase.InitialPosition;
import it.sephiroth.android.library.imagezoom.graphics.FastBitmapDrawable;
/**
* Created by Raul on 24/06/2016.
*/
public abstract class PagedReader extends Reader implements TapListener {
private static ImageViewTouchBase.DisplayType mScreenFit;
protected PageAdapter mPageAdapter;
List<String> paths;
int currentPage = 0;
private InitialPosition iniPosition = InitialPosition.LEFT_UP;
public PagedReader(Context context) {
super(context);
}
public abstract void setPagerAdapter(PageAdapter mPageAdapter);
@Override
public void setScreenFit(ImageViewTouchBase.DisplayType displayType) {
mScreenFit = displayType;
if (mPageAdapter != null)
mPageAdapter.updateDisplayType();
}
@Override
public void setPaths(List<String> paths) {
this.paths = paths;
setPagerAdapter(new PageAdapter());
}
@Override
public void freeMemory() {
setPagerAdapter(null);
}
@Override
public void freePage(int idx) {
if(idx == 0){
if (mPageAdapter != null && mPageAdapter.pages[idx] != null) {
mPageAdapter.pages[idx].unloadImage();
}
} else {
if (mPageAdapter != null && mPageAdapter.pages[idx - 1] != null) {
mPageAdapter.pages[idx - 1].unloadImage();
}
}
}
@Override
public String getPath(int idx) {
if (paths != null) {
if (idx == 0)
return paths.get(idx);
else
return paths.get(idx - 1);
} else
return "";
}
@Override
public void reset() {
setPagerAdapter(null);
currentPage = 0;
}
@Override
public void reloadImage(int idx) {
//Log.d("PR", "idx: " + idx);
if (mPageAdapter != null) {
if(idx > mPageAdapter.pages.length){
Log.e("PagedReader","idx > mPageAdapter.pages.length !");
} else {
if (idx == 0) {
if (mPageAdapter.pages[idx] != null) {
mPageAdapter.pages[idx].setImage();
}
} else {
if (mPageAdapter.pages[idx - 1] != null) {
mPageAdapter.pages[idx - 1].setImage();
}
}
}
}
}
@Override
public void setScrollSensitive(float mScrollSensitive) {
this.mScrollSensitive = mScrollSensitive;
if (mPageAdapter != null)
mPageAdapter.setPageScroll(mScrollSensitive);
}
@Override
public boolean hasFitFeature() {
return true;
}
public class PageAdapter extends PagerAdapter {
private Page[] pages;
PageAdapter(){
pages = new Page[paths.size()];
}
public Page getCurrentPage() {
return pages[currentPage];
}
public void setCurrentPage(int nCurrentPage) {
if (mDirection == Direction.L2R)
nCurrentPage = paths.size() - nCurrentPage;
currentPage = nCurrentPage;
for (int i = 0; i < pages.length; i++) {
if (pages[i] != null) {
if (Math.abs(i - nCurrentPage) <= 1 && !pages[i].imageLoaded) {
pages[i].setImage();
} else if (Math.abs(i - nCurrentPage) > 1 && pages[i].imageLoaded) {
pages[i] = null;
}
}
}
}
Page getPage(int idx){
if (idx < 0)
idx = 0;
else if (idx >= pages.length)
idx = pages.length - 1;
return pages[idx];
}
@Override
public int getCount() {
if (pages != null)
return pages.length;
else return 0;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (mDirection == Direction.L2R)
position = getCount() - position;
Page page = pages[position];
if (pages[position] != null) {
container.addView(page, 0);
} else {
Context context = getContext();
page = new Page(context);
page.setImage(paths.get(position));
container.addView(page, 0);
page.index = position;
pages[position] = page;
}
return page;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
try {
container.removeView((Page) object);
} catch (Exception ignore) {
}
}
public void updateDisplayType() {
for (int i = 0; i < pages.length; i++) {
if (pages[i] != null) {
pages[i].visor.setDisplayType(mScreenFit);
}
}
}
public void setPageScroll(float pageScroll) {
if (pages != null)
for (int i = 0; i < pages.length; i++) {
if (pages[i] != null) {
pages[i].visor.setScrollFactor(pageScroll);
}
}
}
}
public class Page extends RelativeLayout {
public ImageViewTouch visor;
ProgressBar loading;
boolean loadingImage = false;
boolean imageLoaded = false;
int index = 0;
private String path = null;
public Page(Context context) {
super(context);
init();
}
public void init() {
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li = (LayoutInflater) getContext().getSystemService(infService);
li.inflate(R.layout.view_reader_page, this, true);
visor = (ImageViewTouch) findViewById(R.id.visor);
visor.setDisplayType(mScreenFit);
visor.setTapListener(PagedReader.this);
visor.setScaleEnabled(false);
loading = (ProgressBar) findViewById(R.id.loading);
loading.bringToFront();
visor.setScrollFactor(mScrollSensitive);
}
public void unloadImage() {
if (visor != null) {
if (visor.getDrawable() != null)
((FastBitmapDrawable) visor.getDrawable()).getBitmap().recycle();
visor.setImageDrawable(null);
visor.setImageBitmap(null);
}
imageLoaded = false;
loadingImage = false;
}
public void setImage() {
if (!imageLoaded && visor != null && !loadingImage)
new SetImageTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void setImage(String path) {
this.path = path;
setImage();
}
public boolean canScroll(int dx) {
return visor == null || visor.canScroll(dx);
}
public boolean canScrollV(int dx) {
return visor == null || visor.canScrollV(dx);
}
public class SetImageTask extends AsyncTask<Void, Void, Bitmap> {
@Override
protected void onPreExecute() {
loadingImage = true;
if (loading != null)
loading.setVisibility(ProgressBar.VISIBLE);
super.onPreExecute();
}
@Override
protected Bitmap doInBackground(Void... params) {
if (new File(path).exists()) {
boolean notLoaded = true;
int retry = 5;
Bitmap bitmap = null;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
while (notLoaded && retry > 0) {
try {
bitmap = BitmapFactory.decodeFile(path, opts);
notLoaded = false;
} catch (OutOfMemoryError oom) {
retry--;
try {
Thread.sleep(3000);//time to free memory
} catch (InterruptedException ignored) {
}
}
}
return bitmap;
} else {
return null;
}
}
@Override
protected void onPostExecute(Bitmap result) {
if (result != null && visor != null) {
imageLoaded = true;
visor.setScaleEnabled(true);
if (mDirection == Direction.VERTICAL)
visor.setInitialPosition(iniPosition);
else visor.setInitialPosition(ImageViewTouchBase.InitialPosition.LEFT_UP);
if ((result.getHeight() > mTextureMax ||
result.getWidth() > mTextureMax) &&
Build.VERSION.SDK_INT >= 11) {
visor.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
visor.setAlpha(0f);
visor.setImageBitmap(result);
if (index == getCurrentPage()) {
ObjectAnimator.ofFloat(visor, "alpha", 1f).setDuration(500).start();
} else {
visor.setAlpha(1f);
}
loading.setVisibility(ProgressBar.INVISIBLE);
}
loadingImage = false;
super.onPostExecute(result);
}
}
}
}