// Copyright (C) 2010 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.

#pragma version(1)

#pragma rs java_package_name(com.android.wallpaper.holospiral)

#include "rs_graphics.rsh"

#define FOV 60.0f
#define SPIRAL_ROTATE_SPEED 15.0f
#define INNER_ROTATE_SPEED 1.5f
#define OUTER_ROTATE_SPEED 0.5f

// Vertex Shaders
rs_program_vertex gPVBackground;
rs_program_vertex gPVGeometry;

// Fragment Shaders
rs_program_fragment gPFBackground;
rs_program_fragment gPFGeometry;

// Blending and Depth testing
rs_program_store gPSBackground;
rs_program_store gPSGeometry;

// Meshes
rs_mesh gInnerGeometry;
rs_mesh gOuterGeometry;
rs_mesh gBackgroundMesh;

// Matrices
static rs_matrix4x4 gProjectionMatrix;
static rs_matrix4x4 gTransformedModelView;

// Textures
rs_allocation gPointTexture;

// Misc fields
float gXOffset;
float gNearPlane;
float gFarPlane;

// User defined data types
typedef struct VertexShaderConstants_s {
    rs_matrix4x4 modelViewProj;
    float maxPointSize;
    float farPlane;
} VertexShaderConstants;
VertexShaderConstants* gVSConstants;

typedef struct VertexColor_s {
    float3 position;
    float4 color;
} VertexColor;
VertexColor* VertexColor_s_dummy;

static float lastTime;
static float gInnerRotateAngle;
static float gOuterRotateAngle;
static float gWidth;
static float gHeight;

static float modulo360(float val) {
    static const INVERSE_360 = 1.0f / 360.0f;
    int multiplier = (int)(val * INVERSE_360);
    return val - (multiplier * 360.0f);
}

static void drawBackground() {
    rsgBindProgramVertex(gPVBackground);
    rsgBindProgramFragment(gPFBackground);
    rsgBindProgramStore(gPSBackground);

    rsgDrawMesh(gBackgroundMesh);
}

static void drawGeometry(float dt) {
    rsgBindProgramVertex(gPVGeometry);
    rsgBindProgramFragment(gPFGeometry);
    rsgBindProgramStore(gPSGeometry);

    rsgBindTexture(gPFGeometry, 0, gPointTexture);

    rs_matrix4x4 modelView;
    rs_matrix4x4 rotateModelView;

    rsMatrixLoad(&modelView, &gTransformedModelView);
    rsMatrixRotate(&modelView, gXOffset * -SPIRAL_ROTATE_SPEED, 0.0f, 1.0f, 0.0f);

    rsMatrixLoad(&rotateModelView, &modelView);
    {
        rsMatrixRotate(&rotateModelView, -gOuterRotateAngle, 0.0f, 0.0f, 1.0f);
        rsMatrixLoadMultiply(&gVSConstants->modelViewProj, &gProjectionMatrix, &rotateModelView);

        // Wrap the rotation so we don't go past 360
        gOuterRotateAngle = modulo360(gOuterRotateAngle + (dt * OUTER_ROTATE_SPEED));

        rsgDrawMesh(gOuterGeometry);
    }

    rsMatrixLoad(&rotateModelView, &modelView);
    {
        rsMatrixRotate(&rotateModelView, gInnerRotateAngle, 0.0f, 0.0f, 1.0f);
        rsMatrixLoadMultiply(&gVSConstants->modelViewProj, &gProjectionMatrix, &rotateModelView);

        // Wrap the rotation so we don't go past 360
        gInnerRotateAngle = modulo360(gInnerRotateAngle + (dt * INNER_ROTATE_SPEED));

        rsgDrawMesh(gInnerGeometry);
    }
}

void resize(float width, float height) {
    gWidth = width;
    gHeight = height;
    gVSConstants->farPlane = gFarPlane;
    rsMatrixLoadPerspective(&gProjectionMatrix, FOV, gWidth / gHeight, gNearPlane, gFarPlane);
}

void init() {
    gInnerRotateAngle = 0.0f;
    gOuterRotateAngle = 0.0f;

    gXOffset = 0.0f;
    lastTime = rsUptimeMillis();

    // Pre-calculate some fixed transformations
    rsMatrixLoadIdentity(&gTransformedModelView);
    rsMatrixTranslate(&gTransformedModelView, -3.0f, -5.0f, -18.0f);
    rsMatrixRotate(&gTransformedModelView, 20.0f, 0.0f, 1.0f, 0.0f);
    rsMatrixRotate(&gTransformedModelView, -10.0f, 1.0f, 0.0f, 0.0f);
}

int root(void) {
    float now = rsUptimeMillis();
    float elapsed = (now - lastTime) * 0.001f;
    lastTime = now;

    drawBackground();
    drawGeometry(elapsed);

    // Around 14 FPS
    return 70;
}
