package com.visagetechnologies.makeapp;

import android.app.Activity;
import android.content.res.AssetManager;
// import android.media.Image;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import com.visagetechnologies.androidcameraplugin.CameraActivity;
import com.visagetechnologies.bsc.FrameProvider;
import com.visagetechnologies.makeupsdk.Color;
import com.visagetechnologies.makeupsdk.Effect;
import com.visagetechnologies.makeupsdk.FeatureTemplate;
import com.visagetechnologies.makeupsdk.FinishTemplate;
import com.visagetechnologies.makeupsdk.IApplicationLifecycleHandler;
import com.visagetechnologies.makeupsdk.IMakeupObserver;
import com.visagetechnologies.makeupsdk.MakeupEngine;
import com.visagetechnologies.makeupsdk.SDKProvider;
import com.visagetechnologies.makeupsdk.LicenseTypeEnum;
import com.visagetechnologies.makeupsdk.TrackingQuality;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.EnumMap;
import java.util.Map;


class ExternalMakeupObserver implements IMakeupObserver {
  private static String TAG = "ExternalMakeupObserver";

  @Override
  public void OnEffectCreated(MakeupEngine sender, Effect effect) {
    sender.DisplayMakeup(effect);
    Log.d(TAG, "OnEffectCreated effectID: " + Long.toString(effect.GetID()));
  }

  @Override
  public void OnEffectRemoved(MakeupEngine sender, Effect effect) {
    Log.d(TAG, "OnEffectRemoved effectID: " + Long.toString(effect.GetID()));
  }

  @Override
  public void OnEffectHidden(MakeupEngine sender, Effect effect) {
    Log.d(TAG, "OnEffectHidden effectID: " + Long.toString(effect.GetID()));
  }

  @Override
  public void OnEffectDisplayed(MakeupEngine sender, Effect effect) {
    Log.d(TAG, "OnEffectDisplayed effectID: " + Long.toString(effect.GetID()));
  }

  @Override
  public void OnClear(MakeupEngine effect) {
    Log.d(TAG, "OnClear");
  }

  @Override
  public void OnStart(MakeupEngine effect) {
    Log.d(TAG, "OnStart");
  }

  public void OnEffectUpdated(MakeupEngine sender, Effect effect) {
    Log.d(TAG, "OnEffectUpdated effectID: " + Long.toString(effect.GetID()));
  }
}

public class MainActivity extends Activity {

  static {
    System.loadLibrary("BeautySightCore");
    System.loadLibrary("FrameProvider");
  }

  public static String TAG = "MainActivity";

  SDKProvider sdkProvider;
  MakeupEngine makeupEngine;
  IApplicationLifecycleHandler lifecycleHandler;
  ExternalMakeupObserver externalObserver = new ExternalMakeupObserver();

  CameraActivity camera;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    super.onCreate(savedInstanceState);

    AssetManager manager = this.getAssets();
    String licensePath = "";
    try {
      File f = new File(getCacheDir() + "/m1.map");
      if (!f.exists()) {
        try {
          InputStream is = manager.open("license.vlc");
          int size = is.available();
          byte[] buffer = new byte[size];
          is.read(buffer);
          is.close();

          FileOutputStream fos = new FileOutputStream(f);
          fos.write(buffer);
          fos.close();
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
      licensePath = f.getPath();
    } catch (Exception e) {
    }

    Map<LicenseTypeEnum, String> licenses = new EnumMap<LicenseTypeEnum, String>(LicenseTypeEnum.class);
    licenses.put(LicenseTypeEnum.MAKEUP, licensePath);

    sdkProvider = SDKProvider.GetProvider(licenses, this, TrackingQuality.HIGH);
    FrameProvider frameProvider = null;

    try {
      frameProvider = sdkProvider.GetFrameProvider();
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      makeupEngine = sdkProvider.CreateMakeupEngine();
    } catch (Exception e) {
      e.printStackTrace();
    }

    camera = new CameraActivity(this, frameProvider);
    camera.GrabFromCamera();

    makeupEngine.AddObserver(externalObserver);

    FinishTemplate matte = makeupEngine.GetFinishes().Get(0);
    FinishTemplate metallic = makeupEngine.GetFinishes().Get(1);
    FinishTemplate none = makeupEngine.GetFinishes().Get(3);
    FinishTemplate lipgloss = makeupEngine.GetFinishes().Get(4);
    FinishTemplate shimmer = makeupEngine.GetFinishes().Get(5);
    FinishTemplate glitter = makeupEngine.GetFinishes().Get(7);
    FinishTemplate dewy = makeupEngine.GetFinishes().Get(9);
    FinishTemplate luminous = makeupEngine.GetFinishes().Get(10);    


    FeatureTemplate foundationShaded = makeupEngine.GetFeatures().Get(79);
    foundationShaded.elements.get(1).color = new Color(
        198.0f / 255.0f, 165.0f / 255.0f, 142.0f / 255.0f, 30.0f / 255.0f);
    foundationShaded.elements.get(0).color.a = 0.2f;
    makeupEngine.CreateMakeup(foundationShaded, none);

    FeatureTemplate contour = makeupEngine.GetFeatures().Get(30);
    contour.elements.get(0).color = new Color(130.0f / 255.0f, 52.0f / 255.0f,
                                              30.0f / 255.0f, 40.0f / 255.0f);
    makeupEngine.CreateMakeup(contour, matte);

    FeatureTemplate ContourHeart2 = makeupEngine.GetFeatures().Get(71);
    ContourHeart2.elements.get(0).color = new Color(130.0f / 255.0f, 52.0f / 255.0f,
                                              30.0f / 255.0f, 40.0f / 255.0f);
    makeupEngine.CreateMakeup(ContourHeart2, dewy);

    FeatureTemplate lipstick = makeupEngine.GetFeatures().Get(0);
    lipstick.elements.get(0).color = new Color(131.0f / 255.0f, 20.0f / 255.0f,
                                               20.0f / 255.0f, 120.0f / 255.0f);
    makeupEngine.CreateMakeup(lipstick, shimmer);

    FeatureTemplate liplinerUpper = makeupEngine.GetFeatures().Get(91);
    liplinerUpper.elements.get(0).color = new Color(131.0f / 255.0f, 20.0f / 255.0f,
                                               20.0f / 255.0f, 120.0f / 255.0f);
    makeupEngine.CreateMakeup(liplinerUpper, dewy);

    FeatureTemplate liplinerLower = makeupEngine.GetFeatures().Get(90);
    liplinerLower.elements.get(0).color = new Color(131.0f / 255.0f, 20.0f / 255.0f,
                                               20.0f / 255.0f, 120.0f / 255.0f);
    makeupEngine.CreateMakeup(liplinerLower, luminous);

    FeatureTemplate blush = makeupEngine.GetFeatures().Get(11);
    blush.elements.get(0).color = new Color(224.0f / 255.0f, 132.0f / 255.0f,
                                            119.0f / 255.0f, 50.0f / 255.0f);
    makeupEngine.CreateMakeup(blush, matte);

    FeatureTemplate smokey = makeupEngine.GetFeatures().Get(24);
    smokey.elements.get(0).color = new Color(94.0f / 255.0f, 24.0f / 255.0f,
                                             9.0f / 255.0f, 130.0f / 255.0f);
    makeupEngine.CreateMakeup(smokey, matte);

    FeatureTemplate MascaraMediumTopShortBottom = makeupEngine.GetFeatures().Get(82);
    MascaraMediumTopShortBottom.elements.get(0).color =
        new Color(0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
    makeupEngine.CreateMakeup(MascaraMediumTopShortBottom, none);

    FeatureTemplate EyebrowLine = makeupEngine.GetFeatures().Get(50);
    EyebrowLine.elements.get(0).color =
        new Color(0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
    makeupEngine.CreateMakeup(EyebrowLine, none);

    FeatureTemplate EyelinerBox = makeupEngine.GetFeatures().Get(51);
    EyelinerBox.elements.get(0).color =
        new Color(0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
    makeupEngine.CreateMakeup(EyelinerBox, none);

    FeatureTemplate EyebrowsCombedSoft = makeupEngine.GetFeatures().Get(62);
    EyebrowsCombedSoft.elements.get(0).color =
        new Color(0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
    makeupEngine.CreateMakeup(EyebrowsCombedSoft, none);

    FeatureTemplate EyeshadowLid = makeupEngine.GetFeatures().Get(21);
    EyeshadowLid.elements.get(0).color =
        new Color(0.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f);
    makeupEngine.CreateMakeup(EyeshadowLid, none);

    View unityPlayer = makeupEngine.GetView();
    lifecycleHandler = makeupEngine.GetLifecycleHandler();

    setContentView(unityPlayer);
    unityPlayer.requestFocus();

    lifecycleHandler.onResume();
  }

  // Quit Unity
  @Override
  protected void onDestroy() {
    camera.onDestroy();
    lifecycleHandler.onDestroy();
    super.onDestroy(); 
  }

  // Pause Unity
  @Override
  protected void onPause() {
    camera.onPause();
    super.onPause();
    lifecycleHandler.onPause();
  }

  // Resume Unity
  @Override
  protected void onResume() {
    camera.onResume();
    super.onResume();
    lifecycleHandler.onResume();
  }

  // Notify Unity of the focus change.
  @Override
  public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    lifecycleHandler.onWindowFocusChanged(hasFocus);
  }
}
