func (w *Webserver) displayHandler(writer http.ResponseWriter, r *http.Request) {
	buffer := new(bytes.Buffer)
	e := png.Encode(buffer, *w.img)
	tools.ErrorCheck(e)

	writer.Header().Set("Content-Type", "image/png")
	writer.Header().Set("Content-Length", strconv.Itoa(len(buffer.Bytes())))
	_, e = writer.Write(buffer.Bytes())
	tools.ErrorCheck(e)
}
func (f *Framebuffer) Open(device string) {

	fmt.Printf("initializing framebuffer on device %s\n", device)

	file, err := os.OpenFile(device, os.O_RDWR, 0)
	tools.ErrorCheck(err)

	data, err := syscall.Mmap(int(file.Fd()), 0, screensize,
		syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED)
	tools.ErrorCheck(err)

	f.file = file
	f.data = data
}
func StartServer(database *gorm.DB) {

	db = database

	router := web.New(Context{}).
		Middleware(web.LoggerMiddleware).
		Middleware((*Context).QueryVarsMiddleware).
		Middleware(CorsMiddleware).
		Get("/counter", (*Context).CounterHandler).
		Get("/counter/:code", (*Context).CounterByCodeHandler).
		Post("/counter/:code/tick", (*Context).CounterByCodeTickHandler).
		Put("/counter/:code/corr", (*Context).CounterByCodeCorrectHandler).
		Get("/counter/:code/events", (*Context).CounterByCodeEventsHandler).
		Get("/thermometer", (*Context).ThermometerHandler).
		Get("/thermometer/:code", (*Context).ThermometerByCodeHandler).
		Post("/thermometer/:code/reading", (*Context).ThermometerByCodeAddReadingHandler).
		Get("/thermometer/:code/readings", (*Context).ThermometerByCodeGetReadingsHandler).
		Get("/flag", (*Context).FlagHandler).
		Get("/flag/:code", (*Context).FlagByCodeHandler).
		Post("/flag/:code/state", (*Context).FlagByCodeChangeStateHandler).
		Get("/flag/:code/states", (*Context).FlagByCodeGetStatesHandler)

	e := http.ListenAndServe(":8080", router)
	tools.ErrorCheck(e)
}
func (f *Touchscreen) Run() {
	f.Event = make(chan TouchscreenEvent, 64)

	pushed := false

	for {

		inputEvent := InputEvent{}
		err := binary.Read(f.file, binary.LittleEndian, &inputEvent)
		tools.ErrorCheck(err)

		switch {
		case inputEvent.Type == 1 && inputEvent.Value == 1:
			f.tempEvent = TouchscreenEvent{TSEVENT_PUSH, f.tempEvent.X, f.tempEvent.Y}
		case inputEvent.Type == 1 && inputEvent.Value == 0:
			f.tempEvent = TouchscreenEvent{TSEVENT_RELEASE, f.tempEvent.X, f.tempEvent.Y}
		case inputEvent.Type == 3 && inputEvent.Code == 0:
			f.tempEvent.Y = 250 - int32(float32(inputEvent.Value)/3750.0*240.0)
		case inputEvent.Type == 3 && inputEvent.Code == 1:
			f.tempEvent.X = int32(float32(inputEvent.Value)/3827.0*320.0) - 13
		case inputEvent.Type == 0:
			switch {
			case f.tempEvent.Type == TSEVENT_PUSH && !pushed:
				pushed = true
				f.Event <- f.tempEvent
			case f.tempEvent.Type == TSEVENT_RELEASE:
				pushed = false
				f.Event <- f.tempEvent
			}
		}

	}
}
func (w *Webserver) Run() {
	http.HandleFunc("/display", w.displayHandler)
	log.Println("Serving current display image at /display")

	http.HandleFunc("/click", w.clickHandler)
	log.Println("Waiting for click events at /click")

	e := http.ListenAndServe(":8081", nil)
	tools.ErrorCheck(e)
}
func LoadImage(filename string) image.Image {

	f, err := os.Open("images/" + filename)
	tools.ErrorCheck(err)

	var img image.Image = nil

	lowerFilename := strings.ToLower(filename)
	switch {
	case strings.HasSuffix(lowerFilename, ".jpg"):
		img, err = jpeg.Decode(f)
	case strings.HasSuffix(lowerFilename, ".png"):
		img, err = png.Decode(f)
	case strings.HasSuffix(lowerFilename, ".gif"):
		img, err = gif.Decode(f)
	}

	tools.ErrorCheck(err)

	return img
}
func main() {
	db, err := gorm.Open("mysql", "root:root@/rem-dataservice?parseTime=true")
	tools.ErrorCheck(err)

	db.SingularTable(true)

	db.AutoMigrate(&orm.Counter{}, &orm.CounterEvent{},
		&orm.Thermometer{}, &orm.ThermometerReading{},
		&orm.Flag{}, &orm.FlagState{})

	db.Model(&orm.CounterEvent{}).AddForeignKey("counter_id", "counter(id)", "RESTRICT", "RESTRICT")
	db.Model(&orm.ThermometerReading{}).AddForeignKey("thermometer_id", "thermometer(id)", "RESTRICT", "RESTRICT")
	db.Model(&orm.FlagState{}).AddForeignKey("flag_id", "flag(id)", "RESTRICT", "RESTRICT")

	counterChecker := initialization.NewCounterChecker(&db)
	counterChecker.CheckCounters()

	rest.StartServer(&db)
}
func (f *Touchscreen) Open(device string) {
	file, err := os.OpenFile(device, os.O_RDONLY, 0)
	tools.ErrorCheck(err)
	f.file = file
}