﻿var CallModes = { Asynchronous: 1, Synchronous : 2, AllowOne : 3 }; 
var MessageFormatterType = { Pre: 1, Success : 2};
GlobalEventsClass = function() {
    this.onPre = new EventHandler();
    this.onSuccess = new EventHandler();
    this.onFail = new EventHandler();
    this.InPostback = false;
    var PostbackCt = 0;
    this.onPre.Add(this, function() { this.InPostback = true; PostbackCt++; });
    this.onSuccess.Add(this, function() { PostbackCt--; this.InPostback = PostbackCt != 0; });
    this.onFail.Add(this, function() { PostbackCt--; this.InPostback = PostbackCt != 0; });
    var messageFormatters = new Array();
    var runFormatters = function(e) {
        for (var ind = 0; ind < messageFormatters.length; ind++) {
            messageFormatters[ind](e);
        }
    };
    this.onPre.AddSingleParam(this, runFormatters);
    this.onSuccess.AddSingleParam(this, runFormatters);

    this.CallMode = CallModes.AllowOne;
    this.CallQueue = new Array();

    this.VerifyCall = function(instance, method, args) {
        if (this.InPostback) {
            switch (this.CallMode) {
                case CallModes.AllowOne:
                    return false;
                case CallModes.Asynchronous:
                    return true;
                case CallModes.Synchronous:
                    this.CallQueue.push(new { Instance: instance, Method: method, Arguments: args });
                    return false;
            }
        }
        else
            return true;
    };
    var filterMatchingParameters = function(parameter, filter, array) {
        if (!array)
            array = new Array();
        if (typeof (parameter) != 'object') {
            return array;
        }
        if (parameter.length) {
            for (var ind = 0; ind < parameter.length; ind++) {
                filterMatchingParameters(parameter[ind], filter, array);
            }
        }
        if (parameter.__type == filter) {
            array.push(parameter);
        }
        return array;
    };
    //Adds a Message Formatter delegate to the proxy.  A Message Formatter passes a delegate on all parameters, or all parameters
    //that match a specific type either before or after a method has executed.
    this.AddMessageFormatter = function(formatDelegate, eMessageFormatterType, optionalParameterTypeFilter) {
        var formatterMethod = function(e) {
            if (optionalParameterTypeFilter) {
                var filteredParams = filterMatchingParameters(e, optionalParameterTypeFilter);
                for (var ind = 0; ind < filteredParams.length; ind++) {
                    formatDelegate(filteredParams[ind]);
                }
            }
            else
                formatDelegate(e);
        };
        if (eMessageFormatterType == MessageFormatterType.Pre) {
           messageFormatters.push(formatterMethod);
        }
        else {
            messageFormatters.push(formatterMethod);
        }
    };
}
var globalEvents = new GlobalEventsClass();