//TODO timeout connection and try
func (l *Link) startConnTCP(s string, m bool, o *Link, t rocproto.Packet_Section) {

	var listener *net.TCPListener

	log.Println("Starting connection on ", s)
	tcpAddr, err := net.ResolveTCPAddr("tcp", s)
	misc.CheckError(err, "resolving address in linker.go/startConn", true)
	for {
		if m {
			log.Println("Listening on", tcpAddr.String())
			listener, err = net.ListenTCP("tcp", tcpAddr)
			misc.CheckError(err, "listening in linker.go/startConn", true)
			log.Println("Looking for a client...")
			l.conn, err = listener.AcceptTCP()
			misc.CheckError(err, "Accepting client in linker.go/startCnn", true)
			log.Print("Connection acepted")
			listener.Close()
		} else {
			log.Print("Dialing...")
			l.conn, err = net.DialTCP("tcp", nil, tcpAddr)
			misc.CheckError(err, "Dialing adresse in linker.go/startConn", true)
		}
		l.handleConn(o, t)
		log.Println("Closing connection")
		listener.Close()
		l.conn.Close()
		l.conn = nil
	}
}
//Handle websocket connection
//
//The t parameters contain the section to which the handle is associated with Controls<=>Server Video / Controls<=>Client Videos
func (l *Link) handleWS(o *Link, t rocproto.Packet_Section) {

	defer l.ws.Close()
	defer func() { l.ws = nil }()

	quit := make(chan bool)

	go func() {

		defer func() { quit <- true }()

		for {
			m := new(rocproto.Packet)
			_, buff, err := l.ws.ReadMessage()
			if misc.CheckError(err, "Receiving data from conn", false) != nil {
				return
			}
			if err = checkBuffer(-1, buff, m); err != nil {
				e := NewError(rocproto.Error_Packet, err.Error(), int32(t&^rocproto.Packet_CONTROL_SERVER))
				log.Println("Error : ", e)
				l.out <- e
				continue
			}
			log.Println("Received ==>	", m)
			log.Println(m.Header & uint32(t))
			routPacket(m, l, o, t)
		}
	}()
	for {
		select {
		case <-quit:
			return
		case m := <-l.out:
			log.Printf("Sending ==>	%v\n", m)
			b, err := proto.Marshal(m)
			if misc.CheckError(err, "linker.go/handleWS", false) != nil {
				if m == nil {
					return
				}
				continue
			}
			err = l.ws.WriteMessage(websocket.BinaryMessage, b)
			if misc.CheckError(err, "linker.go/handleWS", false) != nil {
				return
			}
		}
	}
}
func (ia *AI) lightDetect(p *rocproto.Packet) error {

	var err error

	p = &rocproto.Packet{Mv: &rocproto.Mv{Speed: 0, Angle: math.Pi / 2}}
	if misc.CheckError(err, "Packing in lightDetect", false) != nil {
		return err
	}
	ia.m.move(p)
	err = ia.light()
	if misc.CheckError(err, "Detecting light", false) != nil {
		return err
	}
	ia.m.Stop()
	return nil
}
//TODO Insert buffer len and check
//Handle TCP connection
//
//The t parameters contain the section to which the handle is associated with Controls<=>Server Video / Controls<=>Client Videos
func (l *Link) handleConn(o *Link, t rocproto.Packet_Section) {

	buff := make([]byte, 128)
	quit := make(chan bool)
	go func() {

		defer func() { quit <- true }()

		m := new(rocproto.Packet)
		for {
			i, err := l.conn.Read(buff[0:])
			if misc.CheckError(err, "Receiving data from conn", false) != nil {
				return
			}
			if err = checkBuffer(i, buff, m); err != nil {
				e := NewError(rocproto.Error_Packet, err.Error(), int32(t&^rocproto.Packet_CONTROL_SERVER))
				log.Println("Error : ", e)
				l.out <- e
				continue
			}
			log.Println("Received ==>	", m)
			routPacket(m, l, o, t)
		}
	}()
	for {
		select {
		case <-quit:
			return
		case m := <-l.out:
			b, err := proto.Marshal(m)
			if misc.CheckError(err, "linker.go/handleConn", false) != nil {
				continue
			}
			_, err = l.conn.Write(b)
			if misc.CheckError(err, "linker.go/handleConn", false) != nil {
				return
			}
		}
	}
}
func (ia *AI) light() error {

	var err error
	d := &DataLux{iter: 0, iterMax: 0, lux: -1, iterMaxLux: 0}
	timeout := time.After(3 * time.Second)
	tick := time.NewTicker(100 * time.Millisecond)
	ia.toggle(true)
	defer ia.toggle(false)
	for {
		select {
		case <-timeout:
			d.iterMax = d.iter
			log.Println("Max lux is at: ", d.getAngle(), " degrees")
			coord := ia.getPos(nil).(rocproto.Coord)
			coord.Lat = coord.Lat + math.Cos(d.getAngle())
			coord.Long = coord.Long + math.Sin(d.getAngle())
			p := goPack.Prepare(uint32(rocproto.AiCodes_DLIGHT), rocproto.Packet_DATA, rocproto.Packet_CONTROL_SERVER, rocproto.Packet_VIDEO_CLIENT)
			p.Coord = &coord
			if err != nil {
				return err
			}
			tick.Stop()
			return ia.Send(p)
		case <-tick.C:
			v, err := ia.sensorLight.Read()
			if misc.CheckError(err, "reading light sensor in photoresistor.go", false) != nil {
				return err
			}
			d.iter += 1
			temp := gobot.ToScale(gobot.FromScale(float64(v), 0, 1024), 0, 255)
			//fmt.Println("Sensor data", temp)
			if diffIsCorrect(d.lux, temp) && temp > d.lux {
				d.lux = temp
				d.iterMaxLux = d.iter
			}
		}
	}
}