-- RAIN DRAINAGE MODELS
-- (C) 2010 INPE AND UFOP

----------------------------------------------------------------
-- Input and output data paths
TERRAME_PATH = "C:\\TerraME\\"
INPUT_PATH = TERRAME_PATH.."Database\\"
OUTPUT_PATH = TERRAME_PATH.."results\\defor\\"

----------------------------------------------------------------
-- Model parameters
-- C = rain/t
-- K = infiltration coefficient

--cellSpaceSize = 100; MAX_MIN = {12.5, 0}; C = 2; K = 0.4; FINAL_TIME = 25; ALT_CHUVA = 200; 		-- original
cellSpaceSize = 100; MAX_MIN = {105 , 0}; C = 2  ; K = 0; FINAL_TIME = 60 ; ALT_CHUVA = 200;  		-- original - no infiltration
-- cellSpaceSize = 100; MAX_MIN = {1040, 0}; C = 2 * 2 ; K = 0; FINAL_TIME = 2* 24; ALT_CHUVA = 0; 	-- rains everywhere
ANYWHERE = false
FINAL_TIME = 3000


----------------------------------------------------------------
-- PART 1 - Retrieve the cell space from the database

csQ = CellularSpace{
	dbType = "ADO",
	database = INPUT_PATH.."cabecaDeBoi.mdb",
	theme = "cells",
	select = { "height", "soilWater" }
}
csQ:load()
createMooreNeighborhood(csQ)
csQ:synchronize()

----------------------------------------------------------------
-- Creates legends and observers

heightLeg = Legend{
		-- Attribute name:  height
		type = TYPES.NUMBER,
		groupingMode = GROUPING.EQUALSTEPS,
		slices = 50,
		precision = 5,
		stdDeviation = STDDEVIATION.NONE,
		maximum = 255,
		minimum = 0,
		colorBar1 = {
			{BLACK, 0},
			{WHITE, 1}
		},
		colorBar2 = {}
}


soilWaterLeg = Legend{
		-- Attribute name:  soilWater
		type = TYPES.NUMBER,
		groupingMode = GROUPING.EQUALSTEPS,
		slices = 100,
		precision = 5,
		stdDeviation = STDDEVIATION.NONE,
		maximum = 105,
		minimum = 0,
		colorBar1 = {
			{WHITE, 0},
			{{170, 255, 255}, 0.242991},
			{{0, 170, 255}, 0.598131},
			{{0, 85, 255}, 3.02804},
			{BLUE, 5.45794},
			{{0, 0, 127}, 10}
		},
		colorBar2 = {}
}


forEachCell( csQ, function(cell)
	if ((cell.x == 19) and (cell.y == 64) ) then
		cell:createObserver(OBSERVERS.DYNAMICGRAPHIC, {"soilWater"}, {"Cell(".. tostring(cell.x)..","..tostring(cell.y)..")", "soilWater", "time", "qtde Agua" } )
		cell:createObserver( OBSERVERS.TABLE, {}, {"Atributos", "Valores"} )
		cell:createObserver( OBSERVERS.TABLE, {"soilWater","x","y", "height", }, {"Atributos", "Valores"} )
		cell:createObserver( OBSERVERS.TEXTSCREEN, {"x","height", "y", "soilWater"}, {} )
		-- cell:createObserver( OBSERVERS.LOGFILE, {"x","height", "y", "soilWater"}, {OUTPUT_PATH.."rain.csv", ";"} )
		cell:notifyObservers()
	end
end)

csQ:createObserver(OBSERVERS.MAP, {"soilWater", "height"}, {soilWaterLeg, heightLeg}) -- cabeca de boi
--csQ:createObserver(OBSERVERS.MAP, {"soilWater"}, {soilWaterLeg})  -- just soilwater map
--csQ:createObserver(OBSERVERS.MAP, {"height"}, {heightLeg})  -- just height map
csQ:notifyObservers()

----------------------------------------------------------------
-- Model initializaion
forEachCell(csQ, function(cell)
		cell.soilWater = 0
		cell:notifyObservers()
end)

----------------------------------------------------------------
-- Model run	
ini = os.time()
for t = 1, FINAL_TIME, 1 do
	-- PART 2: It's raining in the high areas
	forEachCell(csQ,function(cell)
			if ANYWHERE or (cell.height > ALT_CHUVA) then
				cell.soilWater = cell.past.soilWater + C
			end
			cell:notifyObservers(t)
	end)
	csQ:synchronize()
	
	
	-- PART 3: create a temporary variable to store the flow
	forEachCell(csQ, function(cell)
			cell.flow = 0
	end)

		
	-- Calculate the drainage and the flow
	forEachCell(csQ, function(cell)
		  -- PART 4: calculate the drainage
		  cell.soilWater = cell.past.soilWater - K*cell.past.soilWater
		  -- count the lower neighbors
		  countNeigh = 0
		  forEachNeighbor(cell,
		  	function(cell, neigh)
				if (cell ~= neigh) and (cell.height >= neigh.height) then
					countNeigh = countNeigh + 1
				end
			end);
			
			-- PART 5: calculates the flow to neighbors
			if (countNeigh > 0) then
				flow = cell.soilWater / countNeigh
				-- send the water to neighbors
				forEachNeighbor(cell,
					function(cell, neigh)
						if (cell ~= neigh) 
						and (cell.height > neigh.height) then
							neigh.flow = neigh.flow + flow
						end
					end)
			end
	end)
	
	forEachCell(csQ,function(cell)
			cell.soilWater = cell.flow
			cell:notifyObservers(t)		
	end)
		
	csQ:synchronize()
	csQ:notifyObservers(t)
	
	print("t: ", t ,"\n")	 io.flush()
end
endTime = os.time()

----------------------------------------------------------------
print("Elapsed time:", endTime - initialTime)
print("----------------------------------------------------")
print("\n\neof")
io.flush()

