package com.watermarkcreator;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.watermarkcreator.library.BitmapDecoderTask;
import com.watermarkcreator.library.OverlayCreatorTask;
import com.watermarkcreator.library.WaterMarkCreator;


/**
 * Created by b_ashish on 29-Jun-16.
 */
public class MainActivity extends AppCompatActivity {

    private static final int CHOOSE_BASE_PHOTO = 1001;
    private static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 99;

    private Bitmap mSourceBitmap, mWatermarkBitmap;
    private ImageView baseImageView;

    private int mFromTop = 0, mFromLeft = 0;
    private int mAlpha = 255;
    private float mScale = 0.5f;
    private OverlayCreatorTask mOverlayBitmapTask;

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

        final EditText waterMark = (EditText) findViewById(R.id.watermarkText);


        baseImageView = (ImageView) findViewById(R.id.image_holder);

        findViewById(R.id.convert_text_to_bmp).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String waterMarkText = waterMark.getText().toString();
                if (waterMarkText != null && !waterMarkText.equals("")) {
                    placeTextOnImage(waterMarkText);
                } else {
                    Toast.makeText(MainActivity.this, R.string.no_text_to_convert, Toast.LENGTH_LONG).show();
                }
            }
        });

        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                switch (v.getId()) {
                    case R.id.baseImageButton:

                        if (ContextCompat.checkSelfPermission(MainActivity.this,
                                Manifest.permission.READ_EXTERNAL_STORAGE)
                                != PackageManager.PERMISSION_GRANTED) {

                            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                                // Show an explanation to the user *asynchronously* -- don't block
                                // this thread waiting for the user's response! After the user
                                // sees the explanation, try again to request the permission.
                                Toast.makeText(MainActivity.this, "shouldShowRequestPermissionRationale()", Toast.LENGTH_SHORT).show();
                                pickImageFromGallery();
                            } else {

                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                        MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

                            }
                        } else {
                            pickImageFromGallery();
                        }
                        break;
                }
            }
        };


        findViewById(R.id.baseImageButton).setOnClickListener(listener);


        int maxWidth = getDimens(R.id.image_holder)[0];
        int maxHeight = getDimens(R.id.image_holder)[1];

        SeekBar leftSeek = (SeekBar) findViewById(R.id.left_seek);
        leftSeek.setMax(maxWidth);
        leftSeek.setProgress(mFromLeft);

        SeekBar fromTopSeek = (SeekBar) findViewById(R.id.top_seek);
        fromTopSeek.setMax(maxHeight);
        fromTopSeek.setProgress(mFromTop);

        SeekBar scaleSeekBar = (SeekBar) findViewById(R.id.scale_size);
        scaleSeekBar.setProgress((int) (mScale * 100));

        SeekBar opacitySeekBar = (SeekBar) findViewById(R.id.opacity_seek);
        opacitySeekBar.setProgress(mAlpha);

        ((TextView) findViewById(R.id.left_label)).setText(getString(R.string.from_left, mFromLeft));
        ((TextView) findViewById(R.id.top_label)).setText(getString(R.string.from_top, mFromTop));

        ((TextView) findViewById(R.id.scale_label)).setText(getString(R.string.scale_factor, mScale));

        ((TextView) findViewById(R.id.opacity_label)).setText(getString(R.string.opacity_factor, mAlpha));


        leftSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                mFromLeft = progress;

                ((TextView) findViewById(R.id.left_label)).setText(getString(R.string.from_left, mFromLeft));
                invalidateOverlay();

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        fromTopSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                mFromTop = progress;

                ((TextView) findViewById(R.id.top_label)).setText(getString(R.string.from_top, mFromTop));
                invalidateOverlay();

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        scaleSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                mScale = progress / 100f;

                ((TextView) findViewById(R.id.scale_label)).setText(getString(R.string.scale_factor, mScale));
                invalidateOverlay();

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        opacitySeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                mAlpha = progress;

                ((TextView) findViewById(R.id.opacity_label)).setText(getString(R.string.opacity_factor, mAlpha));
                invalidateOverlay();

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        invalidateOverlay();

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted, yay! Do the
                    // storage-related task you need to do.
                    pickImageFromGallery();
                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(MainActivity.this, "You must enable the permission in order to access this feature", Toast.LENGTH_LONG).show();
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }

    }

    private void pickImageFromGallery() {
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
        photoPickerIntent.setType("image/*");
        startActivityForResult(photoPickerIntent, CHOOSE_BASE_PHOTO);
    }

    @Override
    public void onActivityResult(final int requestCode, int resultCode, Intent imageReturnedIntent) {
        super.onActivityResult(requestCode, resultCode, imageReturnedIntent);

        switch (requestCode) {
            case CHOOSE_BASE_PHOTO:
                if (resultCode == Activity.RESULT_OK) {

                    final Uri imageUri = imageReturnedIntent.getData();
                    int dimens[] = getDimens(R.id.image_holder);
                    new BitmapDecoderTask()
                            .setDecodingImageReference(imageUri, getContentResolver())
                            .setRequiredWidth(dimens[0])
                            .setRequiredHeight(dimens[1])
                            .setListener(new BitmapDecoderTask.OnDecodeListener() {
                                @Override
                                public void onDecode(BitmapDecoderTask task, Bitmap bitmap) {

                                    if (requestCode == CHOOSE_BASE_PHOTO) {
                                        mSourceBitmap = bitmap;
                                    }
                                    invalidateOverlay();
                                }
                            })
                            .decode();
                }
        }
    }

    private void placeTextOnImage(CharSequence text) {
        int dimens[] = getDimens(R.id.image_holder);

        WaterMarkCreator.createBuilder().setText(text)
                .setTextMaxWidth((int) convertDpToPixel(dimens[0], MainActivity.this))
                .setTextSize((int) (210))
                .setTextColor(Color.RED).build().setListener(new WaterMarkCreator.OnDecodeListener() {
            @Override
            public void onDecode(WaterMarkCreator task, Bitmap bitmap) {
                mWatermarkBitmap = bitmap;
                invalidateOverlay();
            }
        }).execute();
    }

    public static float convertDpToPixel(float dp, Context context) {
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * ((float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT);
        return px;
    }


    public void invalidateOverlay() {
        if (mSourceBitmap != null && mWatermarkBitmap != null) {
            int maxWidth = mSourceBitmap.getWidth();
            int maxHeight = mSourceBitmap.getHeight();


            SeekBar fromLeftSeek = (SeekBar) findViewById(R.id.left_seek);
            fromLeftSeek.setMax(maxWidth);
            fromLeftSeek.setProgress(mFromLeft);

            SeekBar fromTopSeek = (SeekBar) findViewById(R.id.top_seek);
            fromTopSeek.setMax(maxHeight);
            fromTopSeek.setProgress(mFromTop);


//          If you're working with larger bitmaps and continuously changing the scale value or angle value, you might notice the lag between slider change
//            and the image position. To get rid of that, uncomment the following codes.
            if (mOverlayBitmapTask != null && mOverlayBitmapTask.getStatus() == OverlayCreatorTask.Status.RUNNING) {
                mOverlayBitmapTask.cancel(true);
            }


            mOverlayBitmapTask = new OverlayCreatorTask();
            mOverlayBitmapTask.setBaseBitmap(mSourceBitmap)
                    .setMergeBitmap(mWatermarkBitmap)
                    .setMergeListener(new OverlayCreatorTask.OnMergeListener() {
                        @Override
                        public void onMerge(OverlayCreatorTask task, Bitmap mergedBitmap) {
                            baseImageView.setImageBitmap(mergedBitmap);
                        }
                    })
                    .setScale(mScale)
                    .setOffsets(mFromLeft, mFromTop)
                    .setAlpha(mAlpha)
                    .overlay();

        } else {
            if (mSourceBitmap != null) {
                baseImageView.setImageBitmap(mSourceBitmap);
            }
            if (mWatermarkBitmap != null) {
                Toast.makeText(this, "Base Image required first!", Toast.LENGTH_SHORT).show();
                baseImageView.setImageBitmap(mWatermarkBitmap);
            }
        }

    }

    public int[] getDimens(int resId) {
        int width = findViewById(resId).getMeasuredWidth();
        int height = findViewById(resId).getMeasuredHeight();
        return new int[]{width, height};
    }
}