﻿//helper functions for UpdateProgress control

/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("AsiaAustraliaTech");

/// This function is a patch for UpdateProgress and UpdatePanelAnimationBehavior controls.
/// Typically these controls starts/stops on PageRequestManager update events. When event fires,
/// the control looks to the event args for postback element reference and trying to understand
/// was event fired from the control's target update panel or not, iterating up by the control tree.
/// If the target update panel is found, control begins the action, otherwise skips this event, 
/// assuming that it is raised by another update panel. In this logic UpdatePanel's explicit triggers
/// are missed, the update progress will be never shown if the update fired from this kind of trigger.
/// The function returs true if the postback control is found in the async postback triggers list,
function AsiaAustraliaTech$UpdateProgress$_shouldProcessUpdate(component, targetPanel, postBackElement) {
	if (postBackElement) {
		if (component.Triggers &&
			Array.contains(component.Triggers, postBackElement.id)) {
			return true;
		}        
		var parentNode = postBackElement.parentNode;
		while (parentNode != null &&
			parentNode != targetPanel && 
			component.Triggers &&
			!Array.contains(component.Triggers, parentNode.id)) {
			parentNode = parentNode.parentNode;
		}
		if (parentNode) {
			return true;
		}
	}
	return false;
}

Sys.Application.add_init(function() {

	if (window.AjaxControlToolkit) {
		AjaxControlToolkit.Animation.UpdatePanelAnimationBehavior.prototype._partialUpdateBeginRequest = function(sender, args) {
			AjaxControlToolkit.Animation.UpdatePanelAnimationBehavior.callBaseMethod(this, '_partialUpdateBeginRequest', [sender, args]);
			if (!this._postBackPending) {
				this._postBackPending = true;
				if (AsiaAustraliaTech$UpdateProgress$_shouldProcessUpdate(this, this.get_element(), args.get_postBackElement())) {
					this._onUpdated.quit();
					this._onUpdating.play();
				}
			}
		}
	}
});

Sys.Application.add_init(function() {
	if (window.Sys$UI$_UpdateProgress$_handleBeginRequest) {
		Sys$UI$_UpdateProgress$_handleBeginRequest = function(sender, args) {
			if (this._associatedUpdatePanelId &&
			AsiaAustraliaTech$UpdateProgress$_shouldProcessUpdate(this, $get(this._associatedUpdatePanelId), args.get_postBackElement())) {
				this._timerCookie = window.setTimeout(Function.createDelegate(this, function() { if (this._displayAfter == 0) this.UpdateProgressManager.showProgress(); this._startDelegate(); }), this._displayAfter);
			}
		}
		Sys.UI._UpdateProgress.prototype._handleBeginRequest = Sys$UI$_UpdateProgress$_handleBeginRequest;
	}
});


/// <summary>
/// This class manages the progress indicator over the update panel
///</summary>
AsiaAustraliaTech.UpdateProgressManager = function() {
	AsiaAustraliaTech.UpdateProgressManager.initializeBase(this);

	//fields
	this._UpdatePanel = null;
	this._UpdatePanelID = null;
	this._UpdateProgressControlID = null;
	this._UpdateProgressControl = null;
	this._UpdateProgressExtenderID = null;
	this._UpdateProgressExtender = null;
	this._MinWidth = null;
	this._MinHeight = null;
	this._ControlToCoverID = null;
	this._Triggers = null;

	//delegates
	this._setup$delegate = Function.createDelegate(this, this._setup);
}

AsiaAustraliaTech.UpdateProgressManager.prototype = {

	//properties   
	get_UpdateProgressControlID: function () {
		return this._UpdateProgressControlID;
	},

	set_UpdateProgressControlID: function (value) {
		this._UpdateProgressControlID = value;
	},

	get_UpdateProgressExtenderID: function () {
		return this._UpdateProgressExtenderID;
	},

	set_UpdateProgressExtenderID: function (value) {
		this._UpdateProgressExtenderID = value;
	},

	get_MinWidth: function () {
		return this._MinWidth;
	},

	set_MinWidth: function (value) {
		this._MinWidth = value;
	},

	get_MinHeight: function () {
		return this._MinHeight;
	},

	set_MinHeight: function (value) {
		this._MinHeight = value;
	},

	get_ControlToCoverID: function () {
		return this._ControlToCoverID;
	},

	set_ControlToCoverID: function (value) {
		this._ControlToCoverID = value;
	},

	get_Triggers: function () {
		return this._Triggers;
	},

	set_Triggers: function (value) {
		this._Triggers = value;
	},

	initialize: function () {
		AsiaAustraliaTech.UpdateProgressManager.callBaseMethod(this, 'initialize');
		Sys.Application.add_load(this._setup$delegate);
	},

	dispose: function () {
		AsiaAustraliaTech.UpdateProgressManager.callBaseMethod(this, 'dispose');
	},

	//public methods
	show: function (control) {
		if (control && control.style.display != '') {
			control.style.display = '';
		}
	},

	hide: function (control) {
		if (control && control.style.display != 'none') {
			control.style.display = 'none';
		}
	},

	showProgress: function () {
		var parentControl = this.get_ControlToCoverID() ? $get(this.get_ControlToCoverID()) : this._UpdatePanel;
		this.hide(this._UpdateProgressControl);
		resizeToParent(parentControl, this._UpdateProgressControl, { width: this.get_MinWidth(), height: this.get_MinHeight() });
		if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
			this.show(this._UpdateProgressControl);
		}
	},

	//private methods
	_setup: function () {
		//find update progress control
		this._UpdateProgressControl = $get(this.get_UpdateProgressControlID());
		//hide for first time
		this.hide(this._UpdateProgressControl);
		//find update progress behavior
		var updateProgressComponent = $find(this.get_UpdateProgressControlID());
		//attach trigger list to behavior
		updateProgressComponent.Triggers = this.get_Triggers();
		//add reference to this component
		updateProgressComponent.UpdateProgressManager = this;
		//get update panel id from behavior
		this._UpdatePanelID = updateProgressComponent.get_associatedUpdatePanelId();
		//get update panel control
		this._UpdatePanel = $get(this._UpdatePanelID);
		// find update progress animation extender
		this._UpdateProgressExtender = $find(this.get_UpdateProgressExtenderID());
		//change id in update progress extender animations
		this._setAnimationTarget([this._UpdateProgressExtender.get_OnUpdatingBehavior().get_animation(),
			this._UpdateProgressExtender.get_OnUpdatedBehavior().get_animation()],
			this._UpdateProgressControl);
		//attach trigger list to extender
		this._UpdateProgressExtender.Triggers = this.get_Triggers();
	},

	_setAnimationTarget: function (animations, target) {
		if (animations) {
			for (var i = 0; i < animations.length; ++i) {
				if (animations[i]) {
					//setup reference in update progress extender
					animations[i].UpdateProgressManager = this;
					//set target
					if (animations[i].set_target) {
						animations[i].set_target(target);
					}
					//process children recursive
					if (animations[i].get_animations) {
						this._setAnimationTarget(animations[i].get_animations(), target);
					}
				}
			}
		}
	}


}
AsiaAustraliaTech.UpdateProgressManager.registerClass('AsiaAustraliaTech.UpdateProgressManager', Sys.Component);

if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

