content: /*
   * Copyright (C) 2014 The Android Open Source Project
   *
   * 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.example.android.mediaeffects;
  
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.graphics.Color;
  import android.media.effect.Effect;
  import android.media.effect.EffectContext;
  import android.media.effect.EffectFactory;
  import android.opengl.GLES20;
  import android.opengl.GLSurfaceView;
  import android.opengl.GLUtils;
  import android.os.Bundle;
  import androidx.annotation.Nullable;
  import androidx.fragment.app.Fragment;
  import android.view.LayoutInflater;
  import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.ViewGroup;
  
  import javax.microedition.khronos.egl.EGLConfig;
  import javax.microedition.khronos.opengles.GL10;
  
  public class MediaEffectsFragment extends Fragment implements GLSurfaceView.Renderer {
  
      private static final String STATE_CURRENT_EFFECT = "current_effect";
  
      private GLSurfaceView mEffectView;
      private int[] mTextures = new int[2];
      private EffectContext mEffectContext;
      private Effect mEffect;
      private TextureRenderer mTexRenderer = new TextureRenderer();
      private int mImageWidth;
      private int mImageHeight;
      private boolean mInitialized = false;
      private int mCurrentEffect;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setHasOptionsMenu(true);
      }
  
      @Override
      public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                               @Nullable Bundle savedInstanceState) {
          return inflater.inflate(R.layout.fragment_media_effects, container, false);
      }
  
      @Override
      public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
          mEffectView = view.findViewById(R.id.effectsview);
          mEffectView.setEGLContextClientVersion(2);
          mEffectView.setRenderer(this);
          mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
          if (null != savedInstanceState && savedInstanceState.containsKey(STATE_CURRENT_EFFECT)) {
              setCurrentEffect(savedInstanceState.getInt(STATE_CURRENT_EFFECT));
          } else {
              setCurrentEffect(R.id.none);
          }
      }
  
      @Override
      public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
          inflater.inflate(R.menu.media_effects, menu);
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          setCurrentEffect(item.getItemId());
          mEffectView.requestRender();
          return true;
      }
  
      @Override
      public void onSaveInstanceState(Bundle outState) {
          outState.putInt(STATE_CURRENT_EFFECT, mCurrentEffect);
      }
  
      @Override
      public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
          // Nothing to do here
      }
  
      @Override
      public void onSurfaceChanged(GL10 gl, int width, int height) {
          if (mTexRenderer != null) {
              mTexRenderer.updateViewSize(width, height);
          }
      }
  
      @Override
      public void onDrawFrame(GL10 gl) {
          if (!mInitialized) {
              //Only need to do this once
              mEffectContext = EffectContext.createWithCurrentGlContext();
              mTexRenderer.init();
              loadTextures();
              mInitialized = true;
          }
          if (mCurrentEffect != R.id.none) {
              //if an effect is chosen initialize it and apply it to the texture
              initEffect();
              applyEffect();
          }
          renderResult();
      }
  
      private void setCurrentEffect(int effect) {
          mCurrentEffect = effect;
      }
  
      private void loadTextures() {
          // Generate textures
          GLES20.glGenTextures(2, mTextures, 0);
  
          // Load input bitmap
          Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.puppy);
          mImageWidth = bitmap.getWidth();
          mImageHeight = bitmap.getHeight();
          mTexRenderer.updateTextureSize(mImageWidth, mImageHeight);
  
          // Upload to texture
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]);
          GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
  
          // Set texture parameters
          GLToolbox.initTexParams();
      }
  
      private void initEffect() {
          EffectFactory effectFactory = mEffectContext.getFactory();
          if (mEffect != null) {
              mEffect.release();
          }
          // Initialize the correct effect based on the selected menu/action item
          switch (mCurrentEffect) {
  
              case R.id.none:
                  break;
  
              case R.id.autofix:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_AUTOFIX);
                  mEffect.setParameter("scale", 0.5f);
                  break;
  
              case R.id.bw:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BLACKWHITE);
                  mEffect.setParameter("black", .1f);
                  mEffect.setParameter("white", .7f);
                  break;
  
              case R.id.brightness:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_BRIGHTNESS);
                  mEffect.setParameter("brightness", 2.0f);
                  break;
  
              case R.id.contrast:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CONTRAST);
                  mEffect.setParameter("contrast", 1.4f);
                  break;
  
              case R.id.crossprocess:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CROSSPROCESS);
                  break;
  
              case R.id.documentary:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DOCUMENTARY);
                  break;
  
              case R.id.duotone:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DUOTONE);
                  mEffect.setParameter("first_color", Color.YELLOW);
                  mEffect.setParameter("second_color", Color.DKGRAY);
                  break;
  
              case R.id.filllight:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FILLLIGHT);
                  mEffect.setParameter("strength", .8f);
                  break;
  
              case R.id.fisheye:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FISHEYE);
                  mEffect.setParameter("scale", .5f);
                  break;
  
              case R.id.flipvert:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
                  mEffect.setParameter("vertical", true);
                  break;
  
              case R.id.fliphor:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
                  mEffect.setParameter("horizontal", true);
                  break;
  
              case R.id.grain:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAIN);
                  mEffect.setParameter("strength", 1.0f);
                  break;
  
              case R.id.grayscale:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAYSCALE);
                  break;
  
              case R.id.lomoish:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_LOMOISH);
                  break;
  
              case R.id.negative:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_NEGATIVE);
                  break;
  
              case R.id.posterize:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_POSTERIZE);
                  break;
  
              case R.id.rotate:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_ROTATE);
                  mEffect.setParameter("angle", 180);
                  break;
  
              case R.id.saturate:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SATURATE);
                  mEffect.setParameter("scale", .5f);
                  break;
  
              case R.id.sepia:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SEPIA);
                  break;
  
              case R.id.sharpen:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SHARPEN);
                  break;
  
              case R.id.temperature:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TEMPERATURE);
                  mEffect.setParameter("scale", .9f);
                  break;
  
              case R.id.tint:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TINT);
                  mEffect.setParameter("tint", Color.MAGENTA);
                  break;
  
              case R.id.vignette:
                  mEffect = effectFactory.createEffect(EffectFactory.EFFECT_VIGNETTE);
                  mEffect.setParameter("scale", .5f);
                  break;
  
              default:
                  break;
          }
      }
  
      private void applyEffect() {
          mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]);
      }
  
      private void renderResult() {
          if (mCurrentEffect == R.id.none) {
              // if no effect is chosen, just render the original bitmap
              mTexRenderer.renderTexture(mTextures[0]);
          } else {
              // render the result of applyEffect()
              mTexRenderer.renderTexture(mTextures[1]);
          }
      }
  
  }
  