<commit_before>/*
 * Copyright (C) 2007 The Android Open Source Project
 * Copyright (C) 2012,2013,2014,2015 <NAME>
 *
 * 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.renard.ocr.documents.creation.crop;

import com.google.common.base.Optional;

import com.googlecode.leptonica.android.Box;
import com.googlecode.leptonica.android.Clip;
import com.googlecode.leptonica.android.Pix;
import com.googlecode.leptonica.android.Projective;
import com.googlecode.leptonica.android.Rotate;
import com.googlecode.tesseract.android.OCR;
import com.renard.ocr.HintDialog;
import com.renard.ocr.MonitoredActivity;
import com.renard.ocr.R;
import com.renard.ocr.documents.viewing.grid.DocumentGridActivity;
import com.renard.ocr.util.Util;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import de.greenrobot.event.EventBus;

/**
 * The activity can crop specific region of interest from an image.
 */
public class CropImageActivity extends MonitoredActivity implements BlurWarningDialog.BlurDialogClickListener {
    public static final int RESULT_NEW_IMAGE = RESULT_FIRST_USER + 1;
    private static final int HINT_DIALOG_ID = 2;
    public static final String SCREEN_NAME = "Crop Image";
    private final Handler mHandler = new Handler();

    private int mRotation = 0;
    boolean mSaving;
    private Pix mPix;
    @Bind(R.id.toolbar)
    protected Toolbar mToolbar;
    @Bind(R.id.cropImageView)
    protected CropImageView mImageView;
    @Bind(R.id.crop_layout)
    protected ViewSwitcher mViewSwitcher;
    @Bind(R.id.item_rotate_left)
    protected ImageView mRotateLeft;
    @Bind(R.id.item_rotate_right)
    protected ImageView mRotateRight;
    @Bind(R.id.item_save)
    protected ImageView mSave;


    private CropHighlightView mCrop;
    private Optional<CropData> mCropData = Optional.absent();
    private Optional<PreparePixForCropTask> mPrepareTask = Optional.absent();

    @Override
    public String getScreenName() {
        return "";
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        EventBus.getDefault().register(this);
        getWindow().setFormat(PixelFormat.RGBA_8888);
        setContentView(R.layout.activity_cropimage);
        ButterKnife.bind(this);
        initToolbar();
        initNavigationAsUp();
        startCropping();
    }


    @OnClick(R.id.item_rotate_left)
    public void onRotateLeft() {
        onRotateClicked(-1);
    }

    @OnClick(R.id.item_rotate_right)
    public void onRotateRight() {
        onRotateClicked(1);
    }

    private void onRotateClicked(int delta) {
        if (mCropData.isPresent()) {
            if (delta < 0) {
                delta = -delta * 3;
            }
            mRotation += delta;
            mRotation = mRotation % 4;
            mImageView.setImageBitmapResetBase(mCropData.get().getBitmap(), false, mRotation * 90);
            showDefaultCroppingRectangle(mCropData.get().getBitmap());
        }
    }

    private void startCropping() {
        mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                Bundle extras = getIntent().getExtras();
                final long nativePix = extras.getLong(DocumentGridActivity.EXTRA_NATIVE_PIX);
                final int rotation = extras.getInt(DocumentGridActivity.EXTRA_ROTATION);
                final float margin = getResources().getDimension(R.dimen.crop_margin);
                final int width = (int) (mViewSwitcher.getWidth() - 2 * margin);
                final int height = (int) (mViewSwitcher.getHeight() - 2 * margin);
                mPix = new Pix(nativePix);
                mRotation = rotation / 90;
                mPrepareTask = Optional.of(new PreparePixForCropTask(mPix, width, height));
                mPrepareTask.get().execute();
                mImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

        });
    }


    private void initNavigationAsUp() {
        final Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white);
        getSupportActionBar().setHomeAsUpIndicator(upArrow);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    protected int getHintDialogId() {
        return HINT_DIALOG_ID;
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(final CropData cropData) {
        if (cropData.getBitmap() == null) {
            //should not happen. Scaling of the original document failed some how. Maybe out of memory?
            //TODO send GA event to monitor this
            mAnalytics.sendCropError();
            Toast.makeText(this, R.string.could_not_load_image, Toast.LENGTH_LONG).show();
            onNewImageClicked();
            return;
        }
        mAnalytics.sendBlurResult(cropData.getBlurriness());

        mCropData = Optional.of(cropData);
        adjustOptionsMenu();
        mViewSwitcher.setDisplayedChild(1);

        mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                mImageView.setImageBitmapResetBase(cropData.getBitmap(), true, mRotation * 90);

                switch (cropData.getBlurriness().getBlurriness()) {
                    case NOT_BLURRED:
                        mAnalytics.sendScreenView(SCREEN_NAME);
                        showDefaultCroppingRectangle(cropData.getBitmap());
                        break;
                    case MEDIUM_BLUR:
                    case STRONG_BLUR:
                        zoomToBlurredRegion(cropData);
                        setTitle(R.string.image_is_blurred);
                        BlurWarningDialog dialog = BlurWarningDialog.newInstance((float) cropData.getBlurriness().getBlurValue());
                        final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.add(dialog, BlurWarningDialog.TAG).commitAllowingStateLoss();<commit_msg>fix: don't zoom to blurred region as it can result in jumping<commit_after>/*
 * Copyright (C) 2007 The Android Open Source Project
 * Copyright (C) 2012,2013,2014,2015 <NAME>
 *
 * 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.renard.ocr.documents.creation.crop;

import com.google.common.base.Optional;

import com.googlecode.leptonica.android.Box;
import com.googlecode.leptonica.android.Clip;
import com.googlecode.leptonica.android.Pix;
import com.googlecode.leptonica.android.Projective;
import com.googlecode.leptonica.android.Rotate;
import com.googlecode.tesseract.android.OCR;
import com.renard.ocr.HintDialog;
import com.renard.ocr.MonitoredActivity;
import com.renard.ocr.R;
import com.renard.ocr.documents.viewing.grid.DocumentGridActivity;
import com.renard.ocr.util.Util;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import de.greenrobot.event.EventBus;

/**
 * The activity can crop specific region of interest from an image.
 */
public class CropImageActivity extends MonitoredActivity implements BlurWarningDialog.BlurDialogClickListener {
    public static final int RESULT_NEW_IMAGE = RESULT_FIRST_USER + 1;
    private static final int HINT_DIALOG_ID = 2;
    public static final String SCREEN_NAME = "Crop Image";
    private final Handler mHandler = new Handler();

    private int mRotation = 0;
    boolean mSaving;
    private Pix mPix;
    @Bind(R.id.toolbar)
    protected Toolbar mToolbar;
    @Bind(R.id.cropImageView)
    protected CropImageView mImageView;
    @Bind(R.id.crop_layout)
    protected ViewSwitcher mViewSwitcher;
    @Bind(R.id.item_rotate_left)
    protected ImageView mRotateLeft;
    @Bind(R.id.item_rotate_right)
    protected ImageView mRotateRight;
    @Bind(R.id.item_save)
    protected ImageView mSave;


    private CropHighlightView mCrop;
    private Optional<CropData> mCropData = Optional.absent();
    private Optional<PreparePixForCropTask> mPrepareTask = Optional.absent();

    @Override
    public String getScreenName() {
        return "";
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        EventBus.getDefault().register(this);
        getWindow().setFormat(PixelFormat.RGBA_8888);
        setContentView(R.layout.activity_cropimage);
        ButterKnife.bind(this);
        initToolbar();
        initNavigationAsUp();
        startCropping();
    }


    @OnClick(R.id.item_rotate_left)
    public void onRotateLeft() {
        onRotateClicked(-1);
    }

    @OnClick(R.id.item_rotate_right)
    public void onRotateRight() {
        onRotateClicked(1);
    }

    private void onRotateClicked(int delta) {
        if (mCropData.isPresent()) {
            if (delta < 0) {
                delta = -delta * 3;
            }
            mRotation += delta;
            mRotation = mRotation % 4;
            mImageView.setImageBitmapResetBase(mCropData.get().getBitmap(), false, mRotation * 90);
            showDefaultCroppingRectangle(mCropData.get().getBitmap());
        }
    }

    private void startCropping() {
        mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                Bundle extras = getIntent().getExtras();
                final long nativePix = extras.getLong(DocumentGridActivity.EXTRA_NATIVE_PIX);
                final int rotation = extras.getInt(DocumentGridActivity.EXTRA_ROTATION);
                final float margin = getResources().getDimension(R.dimen.crop_margin);
                final int width = (int) (mViewSwitcher.getWidth() - 2 * margin);
                final int height = (int) (mViewSwitcher.getHeight() - 2 * margin);
                mPix = new Pix(nativePix);
                mRotation = rotation / 90;
                mPrepareTask = Optional.of(new PreparePixForCropTask(mPix, width, height));
                mPrepareTask.get().execute();
                mImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

        });
    }


    private void initNavigationAsUp() {
        final Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white);
        getSupportActionBar().setHomeAsUpIndicator(upArrow);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    protected int getHintDialogId() {
        return HINT_DIALOG_ID;
    }

    @SuppressWarnings("unused")
    public void onEventMainThread(final CropData cropData) {
        if (cropData.getBitmap() == null) {
            //should not happen. Scaling of the original document failed some how. Maybe out of memory?
            //TODO send GA event to monitor this
            mAnalytics.sendCropError();
            Toast.makeText(this, R.string.could_not_load_image, Toast.LENGTH_LONG).show();
            onNewImageClicked();
            return;
        }
        mAnalytics.sendBlurResult(cropData.getBlurriness());

        mCropData = Optional.of(cropData);
        adjustOptionsMenu();
        mViewSwitcher.setDisplayedChild(1);

        mImageView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                mImageView.setImageBitmapResetBase(cropData.getBitmap(), true, mRotation * 90);

                switch (cropData.getBlurriness().getBlurriness()) {
                    case NOT_BLURRED:
                        mAnalytics.sendScreenView(SCREEN_NAME);
                        showDefaultCroppingRectangle(cropData.getBitmap());
                        break;
                    case MEDIUM_BLUR:
                    case STRONG_BLUR:
                       // zoomToBlurredRegion(cropData);
                        setTitle(R.string.image_is_blurred);
                        BlurWarningDialog dialog = BlurWarningDialog.newInstance((float) cropData.getBlurriness().getBlurValue());
                        final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.add(dialog, BlurWarningDialog.TAG).commitAllowingStateLoss();
{'fraction_non_alphanumeric': 0.091053257565746, 'fraction_numerical': 0.006211180124223602, 'mean_word_length': 2.884753593429158, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2146852', 'n_tokens_mistral': 4383, 'n_tokens_neox': 4166, 'n_words': 914}