/*
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

#include "platform_tools/android/apps/arcore/src/main/cpp/hello_ar_application.h"
#include <gtx/string_cast.hpp>

#include <math.h> /* acos */
#include "include/core/SkCanvas.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkMatrix44.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContext.h"
#include "include/gpu/gl/GrGLTypes.h"
#include "include/utils/Sk3D.h"
#include "modules/skottie/include/Skottie.h"
#include "modules/skshaper/include/SkShaper.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/anchor_wrapper.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/glm.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/pending_anchor.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/plane_renderer.h"
#include "platform_tools/android/apps/arcore/src/main/cpp/util.h"
#include "tools/Resources.h"

namespace hello_ar {
    namespace {
        constexpr size_t kMaxNumberOfAndroidsToRender = 1;
        constexpr int32_t kPlaneColorRgbaSize = 16;

        const glm::vec3 kWhite = {255, 255, 255};

        constexpr std::array<uint32_t, kPlaneColorRgbaSize> kPlaneColorRgba = {
                {0xFFFFFFFF, 0xF44336FF, 0xE91E63FF, 0x9C27B0FF, 0x673AB7FF, 0x3F51B5FF,
                        0x2196F3FF, 0x03A9F4FF, 0x00BCD4FF, 0x009688FF, 0x4CAF50FF, 0x8BC34AFF,
                        0xCDDC39FF, 0xFFEB3BFF, 0xFFC107FF, 0xFF9800FF}};

        inline glm::vec3 GetRandomPlaneColor() {
            const int32_t colorRgba = kPlaneColorRgba[std::rand() % kPlaneColorRgbaSize];
            return glm::vec3(((colorRgba >> 24) & 0xff) / 255.0f,
                             ((colorRgba >> 16) & 0xff) / 255.0f,
                             ((colorRgba >> 8) & 0xff) / 255.0f);
        }
    }  // namespace

    HelloArApplication::HelloArApplication(AAssetManager *asset_manager)
            : asset_manager_(asset_manager) {
        LOGI("OnCreate()");
    }

    HelloArApplication::~HelloArApplication() {
        if (ar_session_ != nullptr) {
            ArSession_destroy(ar_session_);
            ArFrame_destroy(ar_frame_);
        }
    }

    void HelloArApplication::OnPause() {
        LOGI("OnPause()");
        if (ar_session_ != nullptr) {
            ArSession_pause(ar_session_);
        }
    }

    void HelloArApplication::OnResume(void *env, void *context, void *activity) {
        LOGI("OnResume()");

        if (ar_session_ == nullptr) {
            ArInstallStatus install_status;
            // If install was not yet requested, that means that we are resuming the
            // activity first time because of explicit user interaction (such as
            // launching the application)
            bool user_requested_install = !install_requested_;

            // === ATTENTION!  ATTENTION!  ATTENTION! ===
            // This method can and will fail in user-facing situations.  Your
            // application must handle these cases at least somewhat gracefully.  See
            // HelloAR Java sample code for reasonable behavior.
            CHECK(ArCoreApk_requestInstall(env, activity, user_requested_install,
                                           &install_status) == AR_SUCCESS);

            switch (install_status) {
                case AR_INSTALL_STATUS_INSTALLED:
                    break;
                case AR_INSTALL_STATUS_INSTALL_REQUESTED:
                    install_requested_ = true;
                    return;
            }

            // === ATTENTION!  ATTENTION!  ATTENTION! ===
            // This method can and will fail in user-facing situations.  Your
            // application must handle these cases at least somewhat gracefully.  See
            // HelloAR Java sample code for reasonable behavior.
            CHECK(ArSession_create(env, context, &ar_session_) == AR_SUCCESS);
            CHECK(ar_session_);

            ArFrame_create(ar_session_, &ar_frame_);
            CHECK(ar_frame_);

            ArSession_setDisplayGeometry(ar_session_, display_rotation_, width_,
                                         height_);
        }

        const ArStatus status = ArSession_resume(ar_session_);
        CHECK(status == AR_SUCCESS);
    }

    void HelloArApplication::OnSurfaceCreated() {
        LOGI("OnSurfaceCreated()");

        background_renderer_.InitializeGlContent();
        point_cloud_renderer_.InitializeGlContent();
        plane_renderer_.InitializeGlContent(asset_manager_);
    }

    void HelloArApplication::OnDisplayGeometryChanged(int display_rotation,
                                                      int width, int height) {
        LOGI("OnSurfaceChanged(%d, %d)", width, height);
        glViewport(0, 0, width, height);
        display_rotation_ = display_rotation;
        width_ = width;
        height_ = height;

        if (ar_session_ != nullptr) {
            ArSession_setDisplayGeometry(ar_session_, display_rotation, width, height);
        }
    }

    void HelloArApplication::OnObjectRotationChanged(int rotation) {
        LOGI("OnObjectRotationChanged(%d)", rotation);
        currentObjectRotation = rotation;
    }

    void HelloArApplication::OnAction(float value) {
        LOGI("OnAction(%.6f)", value);
        currentValue = value;
    }

    void DrawText(SkCanvas *canvas, SkPaint *paint, const char text[]) {
        float spacing = 0.05;
        for (int i = 0; i < sizeof(text) / sizeof(text[0]); i++) {
            const char letter[] = {text[i]};
            size_t byteLength = strlen(static_cast<const char *>(letter));
            canvas->drawText(letter, byteLength, spacing * i, 0, *paint);
        }
    }

    void DrawAxes(SkCanvas *canvas, SkMatrix44 m) {
        SkPaint p;
        p.setStrokeWidth(10);
        SkPoint3 src[4] = {
                {0,   0,   0},
                {0.2, 0,   0},
                {0,   0.2, 0},
                {0,   0,   0.2},
        };
        SkPoint dst[4];
        Sk3MapPts(dst, m, src, 4);

        const char str[] = "XYZ";
        p.setColor(SK_ColorRED);
        canvas->drawLine(dst[0], dst[1], p);

        p.setColor(SK_ColorGREEN);
        canvas->drawLine(dst[0], dst[2], p);

        p.setColor(SK_ColorBLUE);
        canvas->drawLine(dst[0], dst[3], p);
    }

    void DrawVector(SkCanvas *canvas, SkMatrix44 m, glm::vec3 begin, glm::vec3 end, SkColor c) {
        SkPaint p;
        p.setStrokeWidth(15);
        SkPoint3 src[2] = {
                {begin.x, begin.y, begin.z},
                {end.x,   end.y,   end.z}
        };
        SkPoint dst[2];
        Sk3MapPts(dst, m, src, 2);

        const char str[] = "XYZ";
        p.setColor(c);
        canvas->drawLine(dst[0], dst[1], p);
    }

    void DrawBoundingBox(SkCanvas* canvas) {
        SkPaint paint;
        paint.setColor(SK_ColorYELLOW);
        SkIRect bounds = canvas->getDeviceClipBounds();
        SkRect b = SkRect::Make(bounds);

        canvas->drawRect(b, paint);
    }

    void HelloArApplication::OnDrawFrame() {
        grContext = GrContext::MakeGL();

        GrBackendRenderTarget target;
        sk_sp<SkSurface> surface = nullptr;
        GrGLFramebufferInfo framebuffer_info;
        framebuffer_info.fFBOID = 0;
        framebuffer_info.fFormat = 0x8058;


        glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        if (ar_session_ == nullptr) return;

        ArSession_setCameraTextureName(ar_session_,
                                       background_renderer_.GetTextureId());

        // Update session to get current frame and render camera background.
        if (ArSession_update(ar_session_, ar_frame_) != AR_SUCCESS) {
            LOGE("HelloArApplication::OnDrawFrame ArSession_update error");
        }

        // GET CAMERA INFO
        ArCamera *ar_camera;
        ArFrame_acquireCamera(ar_session_, ar_frame_, &ar_camera);

        glm::mat4 view_mat;
        glm::mat4 projection_mat;
        ArCamera_getViewMatrix(ar_session_, ar_camera, glm::value_ptr(view_mat));
        ArCamera_getProjectionMatrix(ar_session_, ar_camera,
                /*near=*/0.1f, /*far=*/100.f,
                                     glm::value_ptr(projection_mat));

        ArTrackingState camera_tracking_state;
        ArCamera_getTrackingState(ar_session_, ar_camera, &camera_tracking_state);
        ArCamera_release(ar_camera);

        background_renderer_.Draw(ar_session_, ar_frame_);

        // If the camera isn't tracking don't bother rendering other objects.
        if (camera_tracking_state != AR_TRACKING_STATE_TRACKING) {
            return;
        }

        // Get light estimation value.
        ArLightEstimate *ar_light_estimate;
        ArLightEstimateState ar_light_estimate_state;
        ArLightEstimate_create(ar_session_, &ar_light_estimate);

        ArFrame_getLightEstimate(ar_session_, ar_frame_, ar_light_estimate);
        ArLightEstimate_getState(ar_session_, ar_light_estimate,
                                 &ar_light_estimate_state);

        // Set light intensity to default. Intensity value ranges from 0.0f to 1.0f.
        // The first three components are color scaling factors.
        // The last one is the average pixel intensity in gamma space.
        float color_correction[4] = {1.f, 1.f, 1.f, 1.f};
        if (ar_light_estimate_state == AR_LIGHT_ESTIMATE_STATE_VALID) {
            ArLightEstimate_getColorCorrection(ar_session_, ar_light_estimate,
                                               color_correction);
        }

        ArLightEstimate_destroy(ar_light_estimate);
        ar_light_estimate = nullptr;
        SkMatrix44 skProj;
        SkMatrix44 skView;
        SkMatrix skViewport;

        skProj = util::GlmMatToSkMat(projection_mat);
        skView = util::GlmMatToSkMat(view_mat);
        skViewport.setScale(width_ / 2, -height_ / 2);
        skViewport.postTranslate(width_ / 2, height_ / 2);
        target = GrBackendRenderTarget(width_, height_, 0, 0, framebuffer_info);
        surface = SkSurface::MakeFromBackendRenderTarget(grContext.get(),
                                                         target,
                                                         kBottomLeft_GrSurfaceOrigin,
                                                         kRGBA_8888_SkColorType,
                                                         nullptr, nullptr);

        // Render Andy objects.
        std::vector<SkMatrix44> models;
        //glm::mat4 model_mat(1.0f);
        for (const auto &obj_iter : tracked_obj_set_) {
            ArTrackingState tracking_state = AR_TRACKING_STATE_STOPPED;
            ArAnchor_getTrackingState(ar_session_, obj_iter, &tracking_state);
            if (tracking_state == AR_TRACKING_STATE_TRACKING) {
                // Render object only if the tracking state is AR_TRACKING_STATE_TRACKING.
                //util::GetTransformMatrixFromAnchor(ar_session_, obj_iter, &model_mat);
                //DRAW ANDY
                //andy_renderer_.Draw(glm::mat4(1), glm::mat4(1), model_mat, color_correction);

                //PREPARE SKIA MATS

                SkMatrix44 skModel;

                switch (currentObjectRotation) {
                    case 0: {
                        auto iter = anchor_skmat4_axis_aligned_map_.find(obj_iter);
                        if (iter != anchor_skmat4_axis_aligned_map_.end()) {
                            skModel = iter->second;
                            models.push_back(skModel);
                        }
                    }
                        break;
                    case 1: {
                        auto iter = anchor_skmat4_camera_aligned_map_.find(obj_iter);
                        if (iter != anchor_skmat4_camera_aligned_map_.end()) {
                            skModel = iter->second;
                            models.push_back(skModel);
                        }
                    }
                        break;
                    case 2: {
                        auto iter = anchor_skmat4_snap_aligned_map_.find(obj_iter);
                        if (iter != anchor_skmat4_snap_aligned_map_.end()) {
                            skModel = iter->second;
                            models.push_back(skModel);
                        }
                    }
                        break;
                    default: {
                        auto iter = anchor_skmat4_axis_aligned_map_.find(obj_iter);
                        if (iter != anchor_skmat4_axis_aligned_map_.end()) {
                            skModel = iter->second;
                            models.push_back(skModel);
                        }
                    }
                        break;
                }

            }
        }

        // Update and render planes.
        ArTrackableList *plane_list = nullptr;
        ArTrackableList_create(ar_session_, &plane_list);
        CHECK(plane_list != nullptr);

        ArTrackableType plane_tracked_type = AR_TRACKABLE_PLANE;
        ArSession_getAllTrackables(ar_session_, plane_tracked_type, plane_list);

        int32_t plane_list_size = 0;
        ArTrackableList_getSize(ar_session_, plane_list, &plane_list_size);
        plane_count_ = plane_list_size;

        for (int i = 0; i < plane_list_size; ++i) {
            ArTrackable *ar_trackable = nullptr;
            ArTrackableList_acquireItem(ar_session_, plane_list, i, &ar_trackable);
            ArPlane *ar_plane = ArAsPlane(ar_trackable);
            ArTrackingState out_tracking_state;
            ArTrackable_getTrackingState(ar_session_, ar_trackable,
                                         &out_tracking_state);

            ArPlane *subsume_plane;
            ArPlane_acquireSubsumedBy(ar_session_, ar_plane, &subsume_plane);
            if (subsume_plane != nullptr) {
                ArTrackable_release(ArAsTrackable(subsume_plane));
                continue;
            }

            if (ArTrackingState::AR_TRACKING_STATE_TRACKING != out_tracking_state) {
                continue;
            }

            ArTrackingState plane_tracking_state;
            ArTrackable_getTrackingState(ar_session_, ArAsTrackable(ar_plane),
                                         &plane_tracking_state);
            if (plane_tracking_state == AR_TRACKING_STATE_TRACKING) {
                const auto iter = plane_color_map_.find(ar_plane);
                glm::vec3 color;
                if (iter != plane_color_map_.end()) {
                    color = iter->second;

                    // If this is an already observed trackable release it so it doesn't
                    // leave aof placing objects on surfaces (n additional reference dangling.
                    ArTrackable_release(ar_trackable);
                } else {
                    // The first plane is always white.
                    if (!first_plane_has_been_found_) {
                        first_plane_has_been_found_ = true;
                        color = kWhite;
                    } else {
                        color = GetRandomPlaneColor();
                    }
                    plane_color_map_.insert({ar_plane, color});
                }

                plane_renderer_.Draw(projection_mat, view_mat, ar_session_, ar_plane,
                                     color);
            }
        }

        ArTrackableList_destroy(plane_list);
        plane_list = nullptr;

        // Update and render point cloud.
        ArPointCloud *ar_point_cloud = nullptr;
        ArStatus point_cloud_status =
                ArFrame_acquirePointCloud(ar_session_, ar_frame_, &ar_point_cloud);
        if (point_cloud_status == AR_SUCCESS) {
            point_cloud_renderer_.Draw(projection_mat * view_mat, ar_session_,
                                       ar_point_cloud);
            ArPointCloud_release(ar_point_cloud);
        }
        SkMatrix44 i = SkMatrix44::kIdentity_Constructor;

        if (surface != nullptr) {
            SkCanvas *canvas = surface->getCanvas();
            SkAutoCanvasRestore acr(canvas, true);
            SkMatrix44 vpv = skViewport * skProj * skView;
            for(SkMatrix44 skModel: models) {
                SkMatrix44 i = SkMatrix44::kIdentity_Constructor;
                canvas->setMatrix(i);
                SkMatrix44 mvpv = skViewport * skProj * skView * skModel;

                //Draw XYZ axes
                DrawAxes(canvas, mvpv);
                //Drawing camera orientation
            /*	DrawVector(canvas, vpv, begins[0], ends[0], SK_ColorMAGENTA);
                DrawVector(canvas, vpv, begins[0], ends[1], SK_ColorYELLOW);
                DrawVector(canvas, vpv, begins[0], ends[2], SK_ColorCYAN);*/

                canvas->concat(mvpv);
                SkPaint paint;

                //Draw Circle
                paint.setColor(0x80700000);
                canvas->drawCircle(0, 0, 0.1, paint);

                //Draw Text
                paint.setColor(SK_ColorBLUE);
                if (currentValue != 0) {
                    paint.setTextSize(currentValue);
                } else {
                    paint.setTextSize(0.1);
                }

                paint.setAntiAlias(true);
                const char text[] = "SkAR";
                size_t byteLength = strlen(static_cast<const char *>(text));
                SkShaper shaper(nullptr);
                SkTextBlobBuilder builder;
                SkPoint p = SkPoint::Make(0, 0);
                shaper.shape(&builder, paint, text, byteLength, true, p, 10);
                canvas->drawTextBlob(builder.make(), 0, 0, paint);

                //DrawBoundingBox(canvas);
            }
            canvas->flush();
        }
    }


    bool HelloArApplication::OnTouchedFirst(float x, float y, int drawMode) {
        LOGI("Entered OnTouchedFirst");
        if (pendingAnchor != nullptr) {
            delete pendingAnchor;
        }
        SkPoint p = SkPoint::Make(x,y);
        pendingAnchor = new PendingAnchor(p);
        bool editAnchor = false;

        if (ar_frame_ != nullptr && ar_session_ != nullptr) {
            ArHitResultList *hit_result_list = nullptr;
            ArHitResultList_create(ar_session_, &hit_result_list);
            CHECK(hit_result_list);
            ArFrame_hitTest(ar_session_, ar_frame_, x, y, hit_result_list);

            int32_t hit_result_list_size = 0;
            ArHitResultList_getSize(ar_session_, hit_result_list, &hit_result_list_size);
            ArHitResult *ar_hit_result = nullptr;
            ArPose *out_pose = nullptr;
            ArPlane* hitPlane = nullptr;
            for (int32_t i = 0; i < hit_result_list_size; ++i) {
                ArHitResult *ar_hit = nullptr;
                ArPose *created_out_pose = nullptr;
                ArHitResult_create(ar_session_, &ar_hit);
                ArHitResultList_getItem(ar_session_, hit_result_list, i, ar_hit);

                if (ar_hit == nullptr) {
                    LOGE("HelloArApplication::OnTouched ArHitResultList_getItem error");
                    return editAnchor;
                }

                ArTrackable *ar_trackable = nullptr;
                ArHitResult_acquireTrackable(ar_session_, ar_hit, &ar_trackable);
                ArTrackableType ar_trackable_type = AR_TRACKABLE_NOT_VALID;
                ArTrackable_getType(ar_session_, ar_trackable, &ar_trackable_type);
                // Creates an anchor if a plane or an oriented point was hit.
                if (AR_TRACKABLE_PLANE == ar_trackable_type) {
                    ArPose *hit_pose = nullptr;
                    ArPose_create(ar_session_, nullptr, &hit_pose);
                    ArHitResult_getHitPose(ar_session_, ar_hit, hit_pose);
                    int32_t in_polygon = 0;
                    ArPlane *ar_plane = ArAsPlane(ar_trackable);
                    ArPlane_isPoseInPolygon(ar_session_, ar_plane, hit_pose, &in_polygon);

                    {
                        // Use hit pose and camera pose to check if hittest is from the
                        // back of the plane, if it is, no need to create the anchor.
                        ArPose *camera_pose = nullptr;
                        ArPose_create(ar_session_, nullptr, &camera_pose);
                        ArCamera *ar_camera;
                        ArFrame_acquireCamera(ar_session_, ar_frame_, &ar_camera);
                        ArCamera_getPose(ar_session_, ar_camera, camera_pose);
                        float normal_distance_to_plane = util::CalculateDistanceToPlane(
                                ar_session_, *hit_pose, *camera_pose);

                        if (!in_polygon || normal_distance_to_plane < 0) {
                            ArPose_destroy(camera_pose);
                            continue;
                        }
                        ArPose_destroy(camera_pose);
                        ArCamera_release(ar_camera);
                    }

                    //Raw pose of hit location
                    float out_hit_raw[] = {0, 0, 0, 0, 0, 0, 0};
                    ArPose_getPoseRaw(ar_session_, hit_pose, out_hit_raw);
                    ArPose_destroy(hit_pose);

                    //Position of anchor
                    glm::vec4 pendingAnchorPos(out_hit_raw[4], out_hit_raw[5], out_hit_raw[6], 1);
                    pendingAnchor->SetContainingPlane(ar_plane);

                    //Check if plane contains approx the same anchor
                    auto planeAnchors = plane_anchors_map_.find(ar_plane);
                    if (planeAnchors != plane_anchors_map_.end()) {
                        //other anchors existed on this plane
                        std::vector<ArAnchor*> anchors = planeAnchors->second;
                        int i = 0;
                        LOGI("Size of anchor list: %d", (int) anchors.size());
                        for(ArAnchor* const& anchor: anchors) {
                            //Get anchor's pose
                            i++;
                            LOGI("CHECKING: Anchor #%d", i);
                            ArPose *anchor_pose = nullptr;
                            ArPose_create(ar_session_, nullptr, &anchor_pose);
                            ArAnchor_getPose(ar_session_, anchor, anchor_pose);
                            float out_anchor_raw[] = {0, 0, 0, 0, 0, 0, 0};
                            ArPose_getPoseRaw(ar_session_, anchor_pose, out_anchor_raw);
                            ArPose_destroy(anchor_pose);
                            glm::vec4 oldAnchorPos(out_anchor_raw[4], out_anchor_raw[5], out_anchor_raw[6], 1);
                            oldAnchorPos = oldAnchorPos - pendingAnchorPos;
                            float distance = util::Magnitude(glm::vec3(oldAnchorPos));
                            if (distance < 0.1f) {
                                LOGI("TouchFirst: Editing old anchor!");
                                editAnchor = true;
                                pendingAnchor->SetArAnchor(anchor);
                                pendingAnchor->SetEditMode(true);

                                ArHitResult_destroy(ar_hit);
                                ArHitResultList_destroy(hit_result_list);
                                LOGI("TouchFirst: Edit %d", editAnchor);
                                return editAnchor;
                            }
                        }
                    }

                    //actual hit result, and containing plane
                    ar_hit_result = ar_hit;
                    hitPlane = ar_plane;

                    //new anchor pos
                    float wanted_raw_pose[] = {0, 0, 0, 0, out_hit_raw[4], out_hit_raw[5], out_hit_raw[6]};
                    ArPose_create(ar_session_, wanted_raw_pose, &created_out_pose);
                    out_pose = created_out_pose;
                    break;
                }
            }


            if (ar_hit_result) {
                LOGI("TouchFirst: Adding new anchor!");
                ArAnchor *anchor = nullptr;
                pendingAnchor->SetEditMode(false);

                if (ArSession_acquireNewAnchor(ar_session_, out_pose, &anchor) != AR_SUCCESS) {
                    LOGE("HelloArApplication::OnTouched ArHitResult_acquireNewAnchor error");
                    LOGI("TouchFirst: Failed to acquire new anchor");
                    delete hitPlane;
                    delete pendingAnchor;
                    pendingAnchor = nullptr;
                    LOGI("TouchFirst: Edit %d", editAnchor);
                    return editAnchor;
                }
                pendingAnchor->SetArAnchor(anchor);

                ArHitResult_destroy(ar_hit_result);
                ArHitResultList_destroy(hit_result_list);
                ArPose_destroy(out_pose);
                hit_result_list = nullptr;
                LOGI("TouchFirst: Edit %d", editAnchor);
                return editAnchor;
            }

            LOGI("TouchFirst: didn't hit anything");
            delete hitPlane;
            delete pendingAnchor;
            pendingAnchor = nullptr;
            LOGI("TouchFirst: Edit %d", editAnchor);
            return editAnchor;
        }
    }

    void HelloArApplication::AddAnchor(ArAnchor* anchor, ArPlane* containingPlane) {
        //delete anchor from matrices maps
        //releasing the anchor if it is not tracking anymore
        ArTrackingState tracking_state = AR_TRACKING_STATE_STOPPED;
        ArAnchor_getTrackingState(ar_session_, anchor, &tracking_state);
        if (tracking_state != AR_TRACKING_STATE_TRACKING) {
            RemoveAnchor(anchor);
            return;
        }

        //releasing the first anchor if we exceeded maximum number of objects to be rendered
        if (tracked_obj_set_.size() >= kMaxNumberOfAndroidsToRender) {
            RemoveAnchor(tracked_obj_set_[0]);
        }

        //updating the containing plane with a new anchor
        auto planeAnchors = plane_anchors_map_.find(containingPlane);
        if (planeAnchors != plane_anchors_map_.end()) {
            //other anchors existed on this plane
            LOGI("TouchFinal: ADDING TO OLD ANCHORS");
            std::vector<ArAnchor*> anchors = planeAnchors->second;
            anchors.push_back(anchor);
            plane_anchors_map_[containingPlane] = anchors;
            anchor_plane_map_.insert({anchor, containingPlane});
        } else {
            LOGI("TouchFinal: NEW SET OF ANCHORS");
            std::vector<ArAnchor*> anchors;
            anchors.push_back(anchor);
            plane_anchors_map_.insert({containingPlane, anchors});
            anchor_plane_map_.insert({anchor, containingPlane});
        }

        tracked_obj_set_.push_back(anchor);
    }

    void HelloArApplication::OnTouchTranslate(float x, float y) {
        LOGI("Entered On Edit Touched");
        ArAnchor *anchor = pendingAnchor->GetArAnchor();
        glm::mat4 matrix = util::SkMatToGlmMat(
                anchor_skmat4_axis_aligned_map_.find(anchor)->second);

        if (ar_frame_ != nullptr && ar_session_ != nullptr) {
            ArHitResultList *hit_result_list = nullptr;
            ArHitResultList_create(ar_session_, &hit_result_list);
            CHECK(hit_result_list);
            ArFrame_hitTest(ar_session_, ar_frame_, x, y, hit_result_list);

            int32_t hit_result_list_size = 0;
            ArHitResultList_getSize(ar_session_, hit_result_list, &hit_result_list_size);
            ArHitResult *ar_hit_result = nullptr;
            ArPose *out_pose = nullptr;
            ArPlane *hitPlane = nullptr;
            for (int32_t i = 0; i < hit_result_list_size; ++i) {
                ArHitResult *ar_hit = nullptr;
                ArPose *created_out_pose = nullptr;
                ArHitResult_create(ar_session_, &ar_hit);
                ArHitResultList_getItem(ar_session_, hit_result_list, i, ar_hit);

                if (ar_hit == nullptr) {
                    LOGE("HelloArApplication::OnTouched ArHitResultList_getItem error");
                    return;
                }

                ArTrackable *ar_trackable = nullptr;
                ArHitResult_acquireTrackable(ar_session_, ar_hit, &ar_trackable);
                ArTrackableType ar_trackable_type = AR_TRACKABLE_NOT_VALID;
                ArTrackable_getType(ar_session_, ar_trackable, &ar_trackable_type);
                // Creates an anchor if a plane or an oriented point was hit.
                if (AR_TRACKABLE_PLANE == ar_trackable_type) {
                    ArPose *hit_pose = nullptr;
                    ArPose_create(ar_session_, nullptr, &hit_pose);
                    ArHitResult_getHitPose(ar_session_, ar_hit, hit_pose);
                    int32_t in_polygon = 0;
                    ArPlane *ar_plane = ArAsPlane(ar_trackable);
                    ArPlane_isPoseInPolygon(ar_session_, ar_plane, hit_pose, &in_polygon);

                    {
                        // Use hit pose and camera pose to check if hittest is from the
                        // back of the plane, if it is, no need to create the anchor.
                        ArPose *camera_pose = nullptr;
                        ArPose_create(ar_session_, nullptr, &camera_pose);
                        ArCamera *ar_camera;
                        ArFrame_acquireCamera(ar_session_, ar_frame_, &ar_camera);
                        ArCamera_getPose(ar_session_, ar_camera, camera_pose);
                        float normal_distance_to_plane = util::CalculateDistanceToPlane(
                                ar_session_, *hit_pose, *camera_pose);

                        if (!in_polygon || normal_distance_to_plane < 0) {
                            ArPose_destroy(camera_pose);
                            continue;
                        }
                        ArPose_destroy(camera_pose);
                        ArCamera_release(ar_camera);
                    }

                    //Raw pose of hit location
                    float out_hit_raw[] = {0, 0, 0, 0, 0, 0, 0};
                    ArPose_getPoseRaw(ar_session_, hit_pose, out_hit_raw);
                    ArPose_destroy(hit_pose);

                    //Translate by new amount
                    glm::vec4 newPos(out_hit_raw[4], out_hit_raw[5], out_hit_raw[6], 1);
                    glm::vec4 oldPos = pendingAnchor->GetAnchorPos(ar_session_);
                    glm::vec3 movement = glm::vec3(newPos - oldPos);


                    //CAMERA SETTINGS
                    glm::mat4 backToOrigin(1);
                    backToOrigin = glm::translate(backToOrigin, -glm::vec3(oldPos));
                    glm::mat4 backToPlane(1);
                    backToPlane = glm::translate(backToPlane, glm::vec3(oldPos));

                    //Axes of Skia object: start with XYZ, totate to get X(-Z)Y, paste on plane, go back to origin --> plane orientation but on origin
                    glm::vec3 objX = glm::normalize(glm::vec3(
                            backToOrigin * matrix *
                            glm::vec4(1, 0, 0, 1))); //X still X
                    glm::vec3 objY = glm::normalize(glm::vec3(
                            backToOrigin * matrix *
                            glm::vec4(0, 1, 0, 1))); //Y is now Z
                    glm::vec3 objZ = glm::normalize(glm::vec3(
                            backToOrigin * matrix *
                            glm::vec4(0, 0, 1, 1))); //Z is now Y


                    glm::mat4 translate(1);
                    translate = glm::translate(translate, movement);
                    matrix = translate * matrix;
                    RemoveAnchor(anchor);



                    //new anchor pos
                    float wanted_raw_pose[] = {0, 0, 0, 0, out_hit_raw[4], out_hit_raw[5],
                                               out_hit_raw[6]};
                    ArPose_create(ar_session_, wanted_raw_pose, &created_out_pose);
                    out_pose = created_out_pose;
                    ar_hit_result = ar_hit;
                    break;
                }
            }

            if (ar_hit_result) {
                LOGI("TouchFirst: Adding new anchor!");
                ArAnchor *anchor = nullptr;
                pendingAnchor->SetEditMode(false);

                if (ArSession_acquireNewAnchor(ar_session_, out_pose, &anchor) != AR_SUCCESS) {
                    LOGE("HelloArApplication::OnTouched ArHitResult_acquireNewAnchor error");
                    LOGI("TouchFirst: Failed to acquire new anchor");
                    delete hitPlane;
                    delete pendingAnchor;
                    pendingAnchor = nullptr;
                    return;
                }
                pendingAnchor->SetArAnchor(anchor);
                anchor_skmat4_axis_aligned_map_[anchor] = util::GlmMatToSkMat(matrix);

                //Add anchor
                AddAnchor(anchor, pendingAnchor->GetContainingPlane());


                ArHitResult_destroy(ar_hit_result);
                ArHitResultList_destroy(hit_result_list);
                ArPose_destroy(out_pose);
                hit_result_list = nullptr;
                return;
            }
        }
    }

    void HelloArApplication::RemoveAnchor(ArAnchor* anchor) {
        //delete anchor from matrices maps
        anchor_skmat4_axis_aligned_map_.erase(anchor);
        anchor_skmat4_camera_aligned_map_.erase(anchor);
        anchor_skmat4_snap_aligned_map_.erase(anchor);

        auto containingPlaneIter = anchor_plane_map_.find(anchor);
        if (containingPlaneIter != anchor_plane_map_.end()) {
            ArPlane*  containingPlane = containingPlaneIter->second;
            auto planeAnchors = plane_anchors_map_.find(containingPlane);
            if (planeAnchors != plane_anchors_map_.end()) {
                //delete this anchor from the list of anchors associated with its plane
                std::vector<ArAnchor*> anchors = planeAnchors->second;
                anchors.erase(std::remove(anchors.begin(), anchors.end(), anchor), anchors.end());
                plane_anchors_map_[planeAnchors->first] = anchors;

                //delete anchor from map of anchor to plane
                anchor_plane_map_.erase(anchor);
            }
        }
        //delete anchor from list of tracked objects
        tracked_obj_set_.erase(std::remove(tracked_obj_set_.begin(), tracked_obj_set_.end(), anchor), tracked_obj_set_.end());
        ArAnchor_release(anchor);
    }

    void HelloArApplication::UpdateMatrixMaps(ArAnchor* anchorKey, glm::mat4 aaMat, glm::mat4 caMat, glm::mat4 snapMat) {
        anchor_skmat4_axis_aligned_map_.insert({anchorKey, util::GlmMatToSkMat(aaMat)});
        anchor_skmat4_camera_aligned_map_.insert({anchorKey, util::GlmMatToSkMat(caMat)});
        anchor_skmat4_snap_aligned_map_.insert({anchorKey, util::GlmMatToSkMat(snapMat)});
    }

    void SetSkiaInitialRotation(glm::mat4& initRotation) {
        initRotation = glm::rotate(initRotation, SK_ScalarPI / 2, glm::vec3(1, 0, 0));
    }

    void SetSkiaObjectAxes(glm::vec3& x, glm::vec3& y, glm::vec3& z, glm::mat4 transform) {
        x = glm::normalize(glm::vec3(transform * glm::vec4(1, 0, 0, 1))); //X still X
        y = glm::normalize(glm::vec3(transform  * glm::vec4(0, 1, 0, 1))); //Y is now Z
        z = glm::normalize(glm::vec3(transform  * glm::vec4(0, 0, 1, 1))); //Z is now Y
    }

    void SetCameraAlignedRotation(glm::mat4& rotateTowardsCamera, float& rotationDirection, const glm::vec3& toProject, const glm::vec3& skiaY, const glm::vec3& skiaZ) {
        glm::vec3 hitLookProj = -util::ProjectOntoPlane(toProject, skiaZ);
        float angleRad = util::AngleRad(skiaY, hitLookProj);
        glm::vec3 cross = glm::normalize(glm::cross(skiaY, hitLookProj));

        //outs
        rotationDirection = util::Dot(cross, skiaZ);
        rotateTowardsCamera = glm::rotate(rotateTowardsCamera, angleRad, rotationDirection * skiaZ);
    }

    struct CameraAlignmentInfo {
        glm::vec3& skiaY, skiaZ;
        glm::mat4& preRot, postRot;

        CameraAlignmentInfo(glm::vec3& skiaY, glm::vec3& skiaZ, glm::mat4 preRot, glm::mat4 postRot)
                : skiaY(skiaY), skiaZ(skiaZ), preRot(preRot), postRot(postRot) {}
    };

    void SetCameraAlignedVertical(glm::mat4& caMat, const glm::mat4& camRot, const CameraAlignmentInfo& camAlignInfo) {
        //Camera axes
        glm::vec3 xCamera = glm::vec3(glm::vec4(1, 0, 0, 1) * camRot);
        glm::vec3 yCamera = glm::vec3(glm::vec4(0, 1, 0, 1) * camRot);
        glm::vec3 zCamera = glm::vec3(glm::vec4(0, 0, -1, 1) * camRot);

        //Get matrix that rotates object from plane towards the wanted angle
        glm::mat4 rotateTowardsCamera(1);
        float rotationDirection = 1;
        SetCameraAlignedRotation(rotateTowardsCamera, rotationDirection, yCamera, camAlignInfo.skiaY, camAlignInfo.skiaZ);

        //LogOrientation(dot, angleRad, "Vertical/Wall");
        glm::mat4 flip(1);
        flip = glm::rotate(flip, SK_ScalarPI, rotationDirection * camAlignInfo.skiaZ);
        caMat = camAlignInfo.postRot * flip * rotateTowardsCamera * camAlignInfo.preRot;
    }

    void SetCameraAlignedHorizontal(glm::mat4& caMat, ArPlaneType planeType, const glm::vec3 hitLook, const CameraAlignmentInfo& camAlignInfo) {
        //Ceiling or Floor: follow hit location
        //Get matrix that rotates object from plane towards the wanted angle
        glm::mat4 rotateTowardsCamera(1);
        float rotationDirection = 1;
        SetCameraAlignedRotation(rotateTowardsCamera, rotationDirection, hitLook, camAlignInfo.skiaY, camAlignInfo.skiaZ);

        if (planeType == ArPlaneType::AR_PLANE_HORIZONTAL_DOWNWARD_FACING) {
            //ceiling
            //LogOrientation(dot, angleRad, "Ceiling");
            glm::mat4 flip(1);
            flip = glm::rotate(flip, SK_ScalarPI, rotationDirection * camAlignInfo.skiaZ);
            caMat = camAlignInfo.postRot * flip * rotateTowardsCamera * camAlignInfo.preRot;
        } else {
            //floor or tabletop
            //LogOrientation(dot, angleRad, "Floor");
            caMat = camAlignInfo.postRot * rotateTowardsCamera * camAlignInfo.preRot;
        }
    }



    void HelloArApplication::SetCameraAlignedMatrix(glm::mat4& caMat, glm::vec3 hitPos, glm::mat4& planeModel, const glm::mat4& initRotation) {
        //Translation matrices: from plane to origin, and from origin to plane
        glm::mat4 backToOrigin(1);
        backToOrigin = glm::translate(backToOrigin, -hitPos);
        glm::mat4 backToPlane(1);
        backToPlane = glm::translate(backToPlane, hitPos);

        //Axes of Skia object: start with XYZ, totate to get X(-Z)Y, paste on plane, go back to origin --> plane orientation but on origin
        glm::vec3 skiaX, skiaY, skiaZ;
        SetSkiaObjectAxes(skiaX, skiaY, skiaZ, backToOrigin * planeModel * initRotation);

        //Get camera position & rotation
        glm::vec3 cameraPos;
        glm::mat4 cameraRotationMatrix;
        util::GetCameraInfo(ar_session_, ar_frame_, cameraPos, cameraRotationMatrix);

        //Set matrix depending on type of surface
        ArPlaneType planeType = AR_PLANE_VERTICAL;
        ArPlane_getType(ar_session_, pendingAnchor->GetContainingPlane(), &planeType);

        //Set CamerAlignmentInfo
        CameraAlignmentInfo camAlignInfo(skiaY, skiaZ, backToOrigin * planeModel * initRotation, backToPlane);

        if (planeType == ArPlaneType::AR_PLANE_VERTICAL) {
            //Wall: follow phone orientation
            SetCameraAlignedVertical(caMat, cameraRotationMatrix, camAlignInfo);
        } else {
            //Ceiling or Floor: follow hit location
            glm::vec3 hitLook(hitPos - cameraPos);
            SetCameraAlignedHorizontal(caMat, planeType, hitLook, camAlignInfo);
        }
    }


    void HelloArApplication::SetModelMatrices(glm::mat4& aaMat, glm::mat4& caMat, glm::mat4& snapMat, const glm::mat4& planeModel) {
        //Brings Skia world to ARCore world
        glm::mat4 initRotation(1);
        SetSkiaInitialRotation(initRotation);

        //Copy plane model for editing
        glm::mat4 copyPlaneModel(planeModel);

        //Set snap matrix
        //snapMat = copyPlaneModel * initRotation;

        //Set axis-aligned matrix
        glm::vec4 anchorPos = pendingAnchor->GetAnchorPos(ar_session_);
        copyPlaneModel[3] = anchorPos;
        aaMat = planeModel * initRotation;

        //Set camera-aligned matrix
        //SetCameraAlignedMatrix(caMat, glm::vec3(anchorPos), copyPlaneModel, initRotation);
    }

    void GetPlaneModelMatrix(glm::mat4& planeModel, ArSession* arSession, ArPlane* arPlane) {
        ArPose *plane_pose = nullptr;
        ArPose_create(arSession, nullptr, &plane_pose);
        ArPlane_getCenterPose(arSession, arPlane, plane_pose);
        util::GetTransformMatrixFromPose(arSession, plane_pose, &planeModel);
        ArPose_destroy(plane_pose);
    }

    void HelloArApplication::OnTouchedFinal(int type) {
        LOGI("Entered OnTouchedFinal");
        if (pendingAnchor == nullptr) {
            LOGI("WARNING: Entered OnTouchedFinal but no pending anchor..");
            return;
        }

        if (pendingAnchor->GetEditMode()) {
            LOGI("WARNING: Editing old anchor in OnTouchedFinal!");
        }

        //Get necessary pending anchor info
        ArPlane* containingPlane = pendingAnchor->GetContainingPlane();
        glm::vec4 pendingAnchorPos = pendingAnchor->GetAnchorPos(ar_session_);
        ArAnchor* actualAnchor = pendingAnchor->GetArAnchor();

        //Plane model matrix
        glm::mat4 planeModel(1);
        GetPlaneModelMatrix(planeModel, ar_session_, containingPlane);

        //Setup skia object model matrices
        glm::mat4 matrixAxisAligned(1);
        glm::mat4 matrixCameraAligned(1);
        glm::mat4 matrixSnapAligned(1);
        SetModelMatrices(matrixAxisAligned, matrixCameraAligned, matrixSnapAligned, planeModel);

        //Update anchor -> model matrix datastructures
        UpdateMatrixMaps(actualAnchor, matrixAxisAligned, matrixCameraAligned, matrixSnapAligned);

        //Add anchor to aux datastructures
        AddAnchor(actualAnchor, containingPlane);
    }

}  // namespace hello_ar
