/*
|----------------------------------------------------------------------------|
|                               Synchronizer                                 |
|----------------------------------------------------------------------------|
*/

Synchronizer.prototype.classNameTag = "synchronizer";

Synchronizer.Instances = new Array();

/*
 * Constructor
 */
function Synchronizer(videoPlayer, audioPlayer, timeSlider) {
    this.index = Synchronizer.Instances.length;
    Synchronizer.Instances[this.index] = this;

    this.videoPlayer = videoPlayer;
    this.audioPlayer = audioPlayer;
    this.timeSlider = timeSlider;
    this.interval = 1000;
    this.syncId = undefined;
}

Synchronizer.prototype.synchronize = function() {
    log('synchronize: ' + this.videoPlayer.playState + ', ' + this.audioPlayer.playState);
    logPlayerErrors(this.videoPlayer);
    logPlayerErrors(this.audioPlayer);

    var time = this.videoPlayer.controls.currentPosition*100;
    var duration = this.videoPlayer.currentMedia.duration*100;
    switch (this.videoPlayer.playState) {
        case Player.PLAY_STATE:
            this.timeSlider.setMaximum(duration);
            this.timeSlider.setValueWithoutNotify(time);
            break;
        case Player.READY_STATE:
            this.timeSlider.setValueWithoutNotify(0);
            break;
        case Player.STOP_STATE:
        case Player.PAUSE_STATE:
        case Player.READY_STATE:
            this.stop();
            break;
    }
    if (this.videoPlayer.playState == Player.PLAY_STATE &&
        this.audioPlayer.playState == Player.PLAY_STATE) {
        var delta = Math.abs(this.videoPlayer.controls.currentPosition - this.audioPlayer.controls.currentPosition);
        if (delta > 0.2) {
            this.audioPlayer.controls.currentPosition = this.videoPlayer.controls.currentPosition;
        }
        log('delta: ' + delta + 's');
    }
}

Synchronizer.prototype.start = function() {
    log('start synchronizer');
    this.syncId = window.setInterval('Synchronizer.Instances['+this.index+'].synchronize()', this.interval);
}

Synchronizer.prototype.stop = function() {
    log('stop synchronizer');
    clearInterval(this.syncId);
}

/*
|----------------------------------------------------------------------------|
|                             utility functions                              |
|----------------------------------------------------------------------------|
*/

Array.prototype.serialize = function(name) {
    var result = '';
    for (var i = 0; i < this.length; i++) {
        if (this[i] != undefined) {
            if (result.length > 0)
                result += '&';
            result += name + "=" + this[i];
        }
    }
    return result;
}

function log(msg) {
    var log = $('log-container');
    if (log != undefined)
        log.innerHTML += '<br/>' + msg;
}

function logPlayerErrors(player) {
    var max = player.error.errorCount;

    for (var i = 0; i < max; i++){
        var errItem = player.error.item(i);
        log(player.id + ' Error: (' + errItem.errorCode + ') ' + errItem.errorDescription);
    }

    player.error.clearErrorQueue();
}

/*
|----------------------------------------------------------------------------|
|                              slider functions                              |
|----------------------------------------------------------------------------|
*/
Range.prototype.setMaximum = function (maximum) {
	if (this._maximum != maximum) {
		var oldIsChanging = this._isChanging;
		this._isChanging = true;

		this._maximum = maximum;

		if (maximum < this._value)
			this.setValue(maximum - this._extent);
		if (maximum < this._minimum) {
			this._extent = 0;
			this.setMinimum(maximum);
			this.setValue(this._maximum);
		}
		if (maximum < this._minimum + this._extent)
			this._extent = this._maximum - this._minimum;
		if (maximum < this._value + this._extent)
			this._extent = this._maximum - this._value;

		this._isChanging = oldIsChanging;
    }
};

Range.prototype.setValueWithoutNotify = function (v) {
    var oldIsChanging = this._isChanging;
    this._isChanging = true;

//    alert('setValue, isChanging: ' + this._isChanging);
    this.setValue(v);

    this._isChanging = oldIsChanging;
};

Slider.prototype.setMaximum = function (v) {
	this._range.setMaximum(v);
	this.input.value = this.getValue();
    this.recalculate();
};

Slider.prototype.setValueWithoutNotify = function (v) {
    this._range.setValueWithoutNotify(v);
    this.input.value = this.getValue();
    this.recalculate();
};
