/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014                                                                    *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef TILE_FRAG_COLOR_HGLSL
#define TILE_FRAG_COLOR_HGLSL

#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
#include "PowerScaling/powerScaling_fs.hglsl"


// Below are all the tiles that are used for contributing 
// the actual fragment color

#if USE_COLORTEXTURE
uniform Layer ColorLayers[NUMLAYERS_COLORTEXTURE];
#endif // USE_COLORTEXTURE

#if USE_GRAYSCALETEXTURE
uniform Layer GrayScaleLayers[NUMLAYERS_GRAYSCALETEXTURE];
#endif // USE_GRAYSCALETEXTURE

#if USE_NIGHTTEXTURE
uniform Layer NightLayers[NUMLAYERS_NIGHTTEXTURE];
#endif // USE_NIGHTTEXTURE

#if USE_OVERLAY
uniform Layer ColorOverlays[NUMLAYERS_OVERLAY];
#endif // USE_OVERLAY

#if USE_GRAYSCALE_OVERLAY
uniform Layer GrayScaleColorOverlays[NUMLAYERS_GRAYSCALE_OVERLAY];
#endif // USE_GRAYSCALE_OVERLAY

#if USE_WATERMASK
uniform Layer WaterMasks[NUMLAYERS_WATERMASK];
#endif // USE_WATERMASK

#if SHOW_HEIGHT_RESOLUTION
uniform vec2 vertexResolution;
#endif

#if USE_ATMOSPHERE
// TODO atmosphere uniforms here
#endif // USE_ATMOSPHERE

#if USE_NIGHTTEXTURE || USE_WATERMASK || USE_ATMOSPHERE || PERFORM_SHADING
	uniform vec3 lightDirectionCameraSpace;
#endif

in vec4 fs_position;
in vec2 fs_uv;
in vec3 ellipsoidNormalCameraSpace;
in vec3 positionCameraSpace;


// levelInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
in LevelWeights levelWeights;


///////////////////////////////////////////////////////////////////// 

// The heightmaps is only used in the fragment shader visually debugging 
// the alignment and resolution of the heightmaps

#if USE_HEIGHTMAP
uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
#endif // USE_HEIGHTMAP

float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){
	float height = CHUNK_DEFAULT_HEIGHT;

#if USE_HEIGHTMAP
	// Calculate desired level based on distance to the vertex on the ellipsoid
    // Before any heightmapping is done
	height = calculateUntransformedHeight(
		uv,
		levelWeights, 							// Variable to determine which texture to sample from
		HeightLayers);	// Three textures to sample from

#endif // USE_HEIGHTMAP

	return height;
}

/////////////////////////////////////////////////////////////////////




/**
 * This method defines the fragment color pipeline which is used in both
 * the local and global chunk rendering. 
 *
 */
vec4 getTileFragColor(){

	vec4 color = vec4(0.1,0.1,0.1,1);

#if USE_COLORTEXTURE

	color = calculateColor(
		fs_uv,
		levelWeights,
		ColorLayers);
#endif // USE_COLORTEXTURE

#if USE_GRAYSCALETEXTURE
	color = calculateGrayScale(
		color,
		fs_uv,
		levelWeights,
		GrayScaleLayers);
#endif // USE_GRAYSCALETEXTURE

#if USE_GRAYSCALE_OVERLAY
	
	color = calculateGrayScaleOverlay(
		color,
		fs_uv,
		levelWeights,
		GrayScaleColorOverlays);

#endif // USE_COLORTEXTURE

#if USE_WATERMASK
	color = calculateWater(
		color,
		fs_uv,
		levelWeights,
		WaterMasks,
		normalize(ellipsoidNormalCameraSpace),
		lightDirectionCameraSpace, // Should already be normalized
		positionCameraSpace);

#endif // USE_WATERMASK

#if USE_NIGHTTEXTURE
	color = calculateNight(
		color,
		fs_uv,
		levelWeights,
		NightLayers,
		normalize(ellipsoidNormalCameraSpace),
		lightDirectionCameraSpace); // Should already be normalized

#endif // USE_NIGHTTEXTURE

#if PERFORM_SHADING
	color = calculateShadedColor(
		color,
		normalize(ellipsoidNormalCameraSpace),
		lightDirectionCameraSpace);
#endif // PERFORM_SHADING

#if USE_ATMOSPHERE
	// Temporary until the real atmosphere code is here
	//color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
	vec3 n = normalize(ellipsoidNormalCameraSpace);
	vec3 l = lightDirectionCameraSpace;
	vec3 c = normalize(positionCameraSpace);
	float cosFactor = 1 - clamp(dot(-n * 0.9, c), 0, 1);
	cosFactor *= 1.1;
	cosFactor -= 0.1;
	cosFactor = clamp(cosFactor, 0, 1);
	cosFactor = cosFactor + pow(cosFactor, 5);
	
	float shadowLight = 0.15;
	float cosFactorLight = pow(max(dot(-l, n), -shadowLight) + shadowLight, 0.8);
	//float cosFactorScatter = pow(max(dot(l, n) + shadowLight, 0), 5);
	//float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0);
	//vec3 r = reflect(l, n);
	//float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20);
	vec3 atmosphereColor = vec3(0.5,0.5,1) * 2;
	color = color + vec4(atmosphereColor,0) * cosFactor * cosFactorLight *  0.5;
#endif // USE_ATMOSPHERE

#if USE_OVERLAY
	color = calculateOverlay(
		color,
		fs_uv,
		levelWeights,
		ColorOverlays);
#endif // USE_OVERLAY



#if SHOW_HEIGHT_INTENSITIES
	color.r *= 0.1;
	color.g *= 0.1;
	color.b *= 0.1;

	float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights);
	float contourLine = fract(10*untransformedHeight) > 0.98 ? 1 : 0;
	color.r += untransformedHeight;
	color.b = contourLine;
#endif


#if SHOW_HEIGHT_RESOLUTION
	color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
	#if USE_HEIGHTMAP
		color.r = min(color.r, 0.8);
		color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
	#endif
#endif


	return color;
}


#endif ///TILE_FRAG_COLOR_HGLSL