// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// 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 once

/* size of screen tiles */
#define TILE_SIZE_X 16
#define TILE_SIZE_Y 16

/* vertex and triangle layout */
struct Vertex   { float x,y,z,r;  }; // FIXME: rename to Vertex4f
struct Triangle { int v0, v1, v2; };

/* include optional vector library */
#include "../math/math.isph"
#include "../math/vec.isph"
#include "../math/affinespace.isph"
#include "ray.isph"
#include "scene_device.isph"

/* include embree API */
#include "../../../include/embree2/rtcore.isph"

/* returns time stamp counter */
extern "C" uniform int64 get_tsc();

/* declare some standard library functions */
extern "C" void abort ();
extern "C" void exit(uniform int);
extern "C" uniform int puts ( const uniform int8* uniform str );
extern "C" uniform int putchar ( uniform int character );

/* face forward for shading normals */
inline Vec3f faceforward( Vec3f N, Vec3f I, Vec3f Ng ) {
  return dot(I, Ng) < 0 ? N : neg(N);
}

/* glut keys codes */
#define GLUT_KEY_F1 1
#define GLUT_KEY_F2 2
#define GLUT_KEY_F3 3
#define GLUT_KEY_F4 4
#define GLUT_KEY_F5 5
#define GLUT_KEY_F6 6
#define GLUT_KEY_F7 7
#define GLUT_KEY_F8 8
#define GLUT_KEY_F9 9
#define GLUT_KEY_F10 10
#define GLUT_KEY_F11 11
#define GLUT_KEY_F12 12

/* standard shading function */
typedef Vec3f (* uniform renderPixelFunc)(float x, float y, const uniform Vec3f& vx, const uniform Vec3f& vy, const uniform Vec3f& vz, const uniform Vec3f& p);

extern void device_key_pressed_default(uniform int key);
extern void (* uniform key_pressed_handler)(uniform int key);

Vec3f renderPixelStandard(float x, float y, const uniform Vec3f& vx, const uniform Vec3f& vy, const uniform Vec3f& vz, const uniform Vec3f& p);

Vec3f renderPixelEyeLight(float x, float y, const uniform Vec3f& vx, const uniform Vec3f& vy, const uniform Vec3f& vz, const uniform Vec3f& p);

Vec3f renderPixelUV(float x, float y, const uniform Vec3f& vx, const uniform Vec3f& vy, const uniform Vec3f& vz, const uniform Vec3f& p);

uniform unsigned int getNumHWThreads();

#define ALIGNED_STRUCT
#define __aligned(x) 

struct Sample3f
{
  Vec3f v;
  float pdf;
};

inline Sample3f make_Sample3f(const Vec3f v, const float pdf) {
  Sample3f s; s.v = v; s.pdf = pdf; return s;
}

/* noise functions */
float noise(const Vec3f& p);
Vec3f noise3D(const Vec3f& p);

/* draws progress bar */
void progressStart();
uniform bool progressMonitor(void* uniform ptr, const uniform double n);
void progressEnd();

Vec2f  getTextureCoordinatesSubdivMesh(void* uniform mesh, const unsigned int primID, const float u, const float v);

float  getTextureTexel1f(void * uniform texture, float u, float v);
Vec3f  getTextureTexel3f(void * uniform texture, float u, float v);
