Index: StatisticsController.groovy
===================================================================
--- StatisticsController.groovy	(revision 62)
+++ StatisticsController.groovy	(revision 63)
@@ -6,6 +6,8 @@
 class StatisticsController {
 
 	def dataSource
+	
+	def graphDataService
 	
     def main = { }
 	
@@ -12,10 +14,12 @@
 	def graphs = {
 	
 		List savedGraphs = new ArrayList()
+		List combinedGraphs = new ArrayList()
 		
 		savedGraphs = EneGraph.list()
+		combinedGraphs = CombGraph.list()
 			
-		[savedGraphs: savedGraphs]
+		[savedGraphs: savedGraphs, combinedGraphs:combinedGraphs]
 			
 	}
 	
@@ -98,40 +102,8 @@
 		String query
 		
 		List data = new ArrayList()
-		def results
-		def db_sql = new Sql(dataSource)
+		data = graphDataService.getGraphData(graphToShow)
 		
-		if(graphToShow.timeFrameType == "day") {
-			db_sql.eachRow "select date_trunc('day',ld.date_recieved) dt, " + graphToShow['type'] + "(to_number(ld.reported_data,'9999999999D99999')) vl from logged_data as ld where (device_id = '" + graphToShow['deviceId'] + "' and date_trunc('day',ld.date_recieved) >= '" + graphToShow.timeFrameStart + "' and date_trunc('day',ld.date_recieved) <= '" + graphToShow.timeFrameEnd + "' and date_part('hour',ld.date_recieved) >= " + graphToShow.advHoursTimeFrameStart + " and date_part('hour',ld.date_recieved) <= " + graphToShow.advHoursTimeFrameEnd + " and date_part('day',ld.date_recieved) >= " + graphToShow.advDayTimeFrameStart + " and date_part('day',ld.date_recieved) <= " + graphToShow.advDayTimeFrameEnd + " and date_part('month',ld.date_recieved) >= " + graphToShow.advMonthTimeFrameStart + " and date_part('month',ld.date_recieved) <= " + graphToShow.advMonthTimeFrameEnd + ") group by date_trunc('day',ld.date_recieved) order by date_trunc('day',ld.date_recieved) asc", {
-				data << [it.dt.getTime(), it.vl]
-			}
-		} else if (graphToShow.timeFrameType == "month") {
-			db_sql.eachRow "select date_trunc('month',ld.date_recieved) dt, " + graphToShow['type'] + "(to_number(ld.reported_data,'9999999999D99999')) vl from logged_data as ld where (device_id = '" + graphToShow['deviceId'] + "' and date_trunc('month',ld.date_recieved) >= '" + graphToShow.timeFrameStart + "' and date_trunc('month',ld.date_recieved) <= '" + graphToShow.timeFrameEnd + "' and date_part('hour',ld.date_recieved) >= " + graphToShow.advHoursTimeFrameStart + " and date_part('hour',ld.date_recieved) <= " + graphToShow.advHoursTimeFrameEnd + " and date_part('day',ld.date_recieved) >= " + graphToShow.advDayTimeFrameStart + " and date_part('day',ld.date_recieved) <= " + graphToShow.advDayTimeFrameEnd + " and date_part('month',ld.date_recieved) >= " + graphToShow.advMonthTimeFrameStart + " and date_part('month',ld.date_recieved) <= " + graphToShow.advMonthTimeFrameEnd + ") group by date_trunc('month',ld.date_recieved) order by date_trunc('month',ld.date_recieved) asc", {
-				data << [it.dt.getTime(), it.vl]
-			}
-		} else if (graphToShow.timeFrameType == "year") {
-			db_sql.eachRow "select date_trunc('year',ld.date_recieved) dt, " + graphToShow['type'] + "(to_number(ld.reported_data,'9999999999D99999')) vl from logged_data as ld where (device_id = '" + graphToShow['deviceId'] + "' and date_trunc('year',ld.date_recieved) >= '" + graphToShow.timeFrameStart + "' and date_trunc('year',ld.date_recieved) <= '" + graphToShow.timeFrameEnd + "' and date_part('hour',ld.date_recieved) >= " + graphToShow.advHoursTimeFrameStart + " and date_part('hour',ld.date_recieved) <= " + graphToShow.advHoursTimeFrameEnd + " and date_part('day',ld.date_recieved) >= " + graphToShow.advDayTimeFrameStart + " and date_part('day',ld.date_recieved) <= " + graphToShow.advDayTimeFrameEnd + " and date_part('month',ld.date_recieved) >= " + graphToShow.advMonthTimeFrameStart + " and date_part('month',ld.date_recieved) <= " + graphToShow.advMonthTimeFrameEnd + ") group by date_trunc('year',ld.date_recieved) order by date_trunc('year',ld.date_recieved) asc", {
-				data << [it.dt.getTime(), it.vl]
-			}
-		} else if (graphToShow.timeFrameType == "custom") {
-			def innerTimeFrame = (long)((graphToShow.timeFrameEnd.getTime() - graphToShow.timeFrameStart.getTime()) / graphToShow.innerSections)
-			query = ""
-			for(int i = 0; i < graphToShow.innerSections;i++) {
-				def currDateMillis = graphToShow.timeFrameStart.getTime() + (i*innerTimeFrame) + innerTimeFrame/2
-				def currDate = new Date((long)currDateMillis)
-				def currDateStartMillis = graphToShow.timeFrameStart.getTime() + (i*innerTimeFrame)
-				def currDateStart = new Date((long)currDateStartMillis)
-				def currDateStopMillis = graphToShow.timeFrameStart.getTime() + ((i+1)*innerTimeFrame)
-				def currDateStop = new Date((long)currDateStopMillis)
-				query += "(select timestamp without time zone '" + currDate.toTimestamp() + "' dt, " + graphToShow['type'] + "(to_number(ld.reported_data,'9999999999D99999')) vl from logged_data as ld where (device_id = '" + graphToShow['deviceId'] + "' and ld.date_recieved >= '" + currDateStart.toTimestamp() + "' and ld.date_recieved <= '" + currDateStop.toTimestamp() + "' and date_part('hour',ld.date_recieved) >= " + graphToShow.advHoursTimeFrameStart + " and date_part('hour',ld.date_recieved) <= " + graphToShow.advHoursTimeFrameEnd + " and date_part('day',ld.date_recieved) >= " + graphToShow.advDayTimeFrameStart + " and date_part('day',ld.date_recieved) <= " + graphToShow.advDayTimeFrameEnd + " and date_part('month',ld.date_recieved) >= " + graphToShow.advMonthTimeFrameStart + " and date_part('month',ld.date_recieved) <= " + graphToShow.advMonthTimeFrameEnd + ")) "
-				if (i < (graphToShow.innerSections-1) ) query += "union "
-			}
-			query += "order by dt asc"
-			db_sql.eachRow(query) {
-				data << [it.dt.getTime(), it.vl]
-			}
-		}
-		
 		[data:data]
 		
 	}
@@ -178,7 +150,7 @@
 		if(!graphToEdit.validate()) {
 			errors += "<p>Graph could not be modified - there were some input errors. Please check if all input values are valid.</p>"
 			flash['errors'] = errors
-			redirect(action:'editGraph')
+			redirect(action:'editGraph',params: [id: params.graphId])
 		} else {
 			if(graphToEdit.save()){
 				flash['confirms'] = "<p>Graph modified succesfully!</p>"
@@ -185,7 +157,7 @@
 				redirect(action:'graphs')
 			} else {
 				flash['errors'] = "<p>There was an error while modifying graph.</p>"
-				redirect(action:'editGraph')
+				redirect(action:'editGraph',params: [id: params.graphId])
 			}
 		}
 		
@@ -448,6 +420,79 @@
 			def graphToDelete = EneGraph.get(params['id'])
 			if(graphToDelete) {
 				
+				if(graphToDelete.delete()) {
+					flash['confirms'] = "<p>Graph deleted successfully.</p>"
+					redirect(action:'graphs')
+					return true
+				} else {
+					flash['errors'] = "<p>Cannot remove this graph. This graph is part of a <b>combined</b> graph.</p><p>You should remove the <b>combined</b> graph first.</p>"
+					redirect(action:'graphs')
+					return false
+				}
+				
+			} else {
+				flash['errors'] = "<p>No graph was deleted. Graph ID invalid!</p>"
+				redirect(action:'graphs')
+				return false
+			}
+			
+		} else {
+		
+			flash['errors'] = "<p>No graph was deleted. Graph ID not specified!</p>"
+			redirect(action:'graphs')
+			return false
+		
+		}	
+		
+	}
+	
+	def newCombGraph = {
+		
+		def graphs = EneGraph.list()
+		
+		[graphs:graphs]
+		
+	}
+	
+	def newCombGraphDo = {
+		
+		List selgrph = new ArrayList()
+		selgrph = params.list('graphsToCombine')
+		
+		if(selgrph.size() < 2) {
+			flash.errors = "<p>You have to select at least 2 single device graphs to combine!</p>"
+			redirect(action:'newCombGraph')
+			return false
+		}
+		
+		CombGraph newOne = new CombGraph(
+			name: params.newCombGraphName
+		)
+		
+		selgrph.each {
+			newOne.addToGraphs(EneGraph.get(it))
+		}
+		
+		if(newOne.validate()) {
+			newOne.save()
+			flash.confirms = "<p>New combined graph added succesfully!</p>"
+			redirect(action:'graphs')
+			return true
+		} else {
+			flash.errors = "<p>New graph could not be created. Check if all fields are filled and if values are valid.</p>"
+			redirect(action:'newCombGraph')
+			return false
+		}
+		
+	}
+	
+	def deleteCombGraph = {
+		
+		if(params['id']) {
+			
+			def graphToDelete = CombGraph.get(params['id'])
+			if(graphToDelete) {
+				
 				graphToDelete.delete()
 				flash['confirms'] = "<p>Graph deleted successfully.</p>"
 				redirect(action:'graphs')
@@ -465,8 +510,103 @@
 			redirect(action:'graphs')
 			return false
 		
-		}	
+		}
 		
 	}
+	
+	def editCombGraph = {
+		
+		CombGraph chosenGraph = CombGraph.get(params['id'])
+		List allGraphs = new ArrayList()
+		EneGraph.list().each {
+			if(chosenGraph.graphs.contains(it)) {
+				allGraphs << [gr: it, sl: true]
+			} else {
+				allGraphs << [gr: it, sl: false]
+			}
+		}
+		
+		[chosenGraph: chosenGraph, graphs: allGraphs]
+		
+	}
+	
+	def editCombGraphDo = {
+		
+		CombGraph chosenGraph = CombGraph.get(params['graphId'])
+		
+		chosenGraph.name = params['editCombGraphName']
+		List newGraphs = new ArrayList()
+		newGraphs = params.list('graphsToCombine')
+		
+		if(newGraphs.size() < 2) {
+			flash.errors = "<p>You have to select at least 2 single device graphs to combine!</p>"
+			redirect(action:'editCombGraph',params:[id: params.graphId])
+			return false
+		}
+		
+		List graphsToRemove = new ArrayList()
+		
+		chosenGraph.graphs.each {
+			graphsToRemove << it
+		}
+		
+		graphsToRemove.each {
+			chosenGraph.removeFromGraphs(it)
+		}
+		
+		newGraphs.each {
+			chosenGraph.addToGraphs(EneGraph.get(it))
+		}
+		
+		if(chosenGraph.validate()) {
+			if(chosenGraph.save(flush:true)) {
+				flash.confirms = "<p>Graph edited succesfully!</p>"
+				redirect(action:'graphs')
+				return true
+			} else {
+				flash.errors = "<p>Graph could not be edited. Check if all fields are filled and if values are valid.</p>"
+				redirect(action:'editCombGraph', params:[id: params.graphId])
+				return false
+			}
+		} else {
+			flash.errors = "<p>Graph could not be edited. Check if all fields are filled and if values are valid.</p>"
+			redirect(action:'editCombGraph', params:[id: params.graphId])
+			return false
+		}
+		
+	}
+	
+	def showCombGraph = {
+		
+		if(params.id) {
+			CombGraph chGrph = CombGraph.get(params.id)
+			if(chGrph) {
+				
+				List datas = new ArrayList()
+				
+				chGrph.graphs.each {
+					datas << graphDataService.getGraphData(it)
+				}
+				
+				return [data: datas]
+				
+			} else {
+				flash.errors = "<p>Invalid graph ID!</p>"
+				redirect(action:'graphs')
+				return false
+			}
+		} else {
+			flash.errors = "<p>Invalid graph ID!</p>"
+			redirect(action:'graphs')
+			return false
+		}
+		
+	}
+	
+	def makeCombReport = {
+		
+		
+		
+	}
 	
 }
