/**
 * Timer service as per Timer XML description
 *
 * The timer service has two state vbls, Time and TimeValid.
 * Time is continually changing, updated every second. If we kept this
 * state in the cybergarage state vbl (which is a string) then every
 * second we would be parsing the string into a Time object, incrementing
 * it and then turning it back into a string. Kind of wasteful. So it is
 * (maybe) better to keep the state in a Time object (in the Ticker) and 
 * just copy it into the cybergarage state vbl on each change. On the other hand,
 * TimeValid changes rarely and isn't checked much, so we can keep it
 * in the cybergarage state vbl always
 */
package service;

import xmltypes.*;
import org.cybergarage.upnp.Service;
import org.cybergarage.upnp.StateVariable;

public class TickerTimer implements Timer {

    private Ticker ticker;

    // Change start
    private Service service;
    private StateVariable timeVar;
    private StateVariable validVar;
    // Change end

    public TickerTimer() {
    }

    // Change start
    public void setService(Service svc) {
	service = svc;

	Time time = new Time("12:00:00");

	timeVar = svc.getStateVariable("Time");
	timeVar.setValue(time.toString());

	validVar = svc.getStateVariable("TimeValid");
	validVar.setValue("false");
	
	ticker = new Ticker(time, timeVar);
	ticker.start();
    }
    // Change end

    public void setTime(Time t) {
	if (ticker != null) {
	    ticker.stopRunning();
	}

	// Change start
	timeVar.setValue(t.toString());
	validVar.setValue("true");
	// Change end

	ticker = new Ticker(t, timeVar);
	ticker.start();
    }

    public Time getTime() {
	Time time = new Time(timeVar.getValue());
	return time;
    }

    public boolean isValidTime() {
	if (validVar.getValue().equals("true")) {
	    return true;
	} else {
	    return false;
	}
    }
}

class Ticker extends Thread {
    private Time time;
    private boolean keepRunning = true;
    // Change start
    private StateVariable timeVar;
    // Change end

    // Change start
    public Ticker(Time t, StateVariable tVar) {
	time = t;
	timeVar = tVar;
    }
    // Change end

    public void run() {
	while (keepRunning) {
	    try {
		sleep(1000);
	    } catch(InterruptedException e) {
	    }
	    if (keepRunning) {
		time.increment();
		// Change start
		timeVar.setValue(time.toString());
		// Change end
	    }
	}
    }

    public void stopRunning() {
	keepRunning = false;
    }
}
