﻿function CSMessageTypeInfo(msgName, callFunc) {
    this.messageName = msgName;
    this.callbackFunc = callFunc;
}

function CSMessageQue() {
    this.isInitialised = false;
    this.callbackQue = new Array();
    this.messageTypes = new Array();
    this.onMessageReceived = new Array();

    this.Initialise = function() {
        try {
            //This cannot be used when a function is called so store as a var reference
            //and call the verable to get beck into the object
            var self = this;

            if (window.attachEvent) {
                window.attachEvent('onmessage', function(event) { self.receiveMessage(event); });
                this.isInitialised = true;
            }
            else if (window.addEventListener) {
                window.addEventListener("message", function(event) { self.receiveMessage(event); }, false);
                this.isInitialised = true;
            }
        }
        catch (ex) {
            isInitialised = false;
        }
    };

    this.AddMsgListner = function(msgName, callBack) {
        for (var i = 0; i < this.messageTypes.length; i++) {
            if (this.messageTypes[i].messageName == msgName &&
                this.messageTypes[i].callbackFunc == callBack) {
                //If the message listener & function is already there then return
                return;
            }
        }

        var msgType = new CSMessageTypeInfo(msgName, callBack);
        this.messageTypes[this.messageTypes.length] = msgType;
    };
    this.RemoveMsgListner = function(msgName, callBack) {
        for (var i = this.messageTypes.length - 1; i > 0; i--) {
            if (this.messageTypes[i].messageName == msgName &&
                this.messageTypes[i].callbackFunc == callBack) {
                this.messageTypes.splice(i, 1);
                return;
            }
        }
    };

    this.AddOnMessageReceived = function(callBack) {
        for (var i = 0; i < this.onMessageReceived.length; i++) {
            if (this.onMessageReceived[i] == callBack) {
                //If the function is already there then return
                return;
            }
        }

        this.onMessageReceived[this.onMessageReceived.length] = callBack;
    };
    this.RemoveOnMessageReceived = function(callBack) {
        for (var i = this.onMessageReceived.length - 1; i > 0; i--) {
            if (this.onMessageReceived[i] == callBack) {
                this.onMessageReceived.splice(i, 1);
                return;
            }
        }
    };

    this.receiveMessage = function(event) {

        var mData = event.data.split('#');
        var eData = mData[0].split('=');

        if (eData[0] != 'e') return;

        switch (eData[1]) {
            case "resizeFrame": this.ResizeFrameEvent(event, mData[1]); break;
            case "resizeWidth": this.ResizeFrameWidthEvent(event, mData[1]); break;
            case "resizeHeight": this.ResizeFrameHeightEvent(event, mData[1]); break;
            case "requestHeight": this.ReturnDocumentHeight(event); break;
            case "requestWidth": this.ReturnDocumentWidth(event); break;
            default: this.ProcessMessage(event, eData[1], mData[1]); break;
        }

        this.OnMessageReceived(event, eData[1], mData[1]);
        
        return;

        /*var fData = event.data.split(';');

                var strFrame = GetParamValue(fData, "f");
        if (strFrame == null) return;

                var aFrameObj = document.getElementById(strFrame);
        if (!aFrameObj) return;

                aFrameObj.style.height = GetParamValueDef(fData, "h", aFrameObj.style.height);
        //aFrameObj.style.width = GetParamValueDef(fData, "w", aFrameObj.style.width);
        if (event.origin !== "http://example.org:8080");
        return;

                if (event.data == 'Hello World') {
        event.source.postMessage('Hello');
        } else {
        alert(event.data);
        }*/
    };

    this.ProcessMessage = function(event, msgName, data) {
        try {
            for (var i = 0; i < this.messageTypes.length; i++) {
                if (this.messageTypes[i].messageName == msgName) {
                    if (this.messageTypes[i].callbackFunc) {
                        try {
                            this.messageTypes[i].callbackFunc(msgName, data);
                            //return; -- Loop through all message listerners as there may be more
                            //than 1 listening for the same message
                        }
                        catch (ex) {
                        }
                    }
                }
            }
        }
        catch (ex) {
        }
    };

    this.OnMessageReceived = function(event, msgName, data) {
        try {
            for (var i = 0; i < this.onMessageReceived.length; i++) {
                if (this.onMessageReceived[i]) {
                    try {
                        this.onMessageReceived[i](event.source, msgName, data);
                        //return; -- Loop through all message listerners as there may be more
                        //than 1 listening for the same message
                    }
                    catch (ex) {
                    }
                }
            }
        }
        catch (ex) {
        }
    };

    this.ResizeFrameEvent = function(event, arrParams) {
        var fData = arrParams.split(';');

        var strFrame = this.GetParamValue(fData, "f");
        if (strFrame == null) return;

        var aFrameObj = document.getElementById(strFrame);
        if (!aFrameObj) return;

        //Set the style height to override attribute height if set
        aFrameObj.style.height = this.GetParamValueDef(fData, "h", aFrameObj.style.height) + "px";

        //Now the height has been adjusted so there is no scrollbar set the width if required
        if (this.GetParamValueDef(fData, "autoW", "false") == "true")
            this.SendMessageDest(event.source, "requestWidth", "", "*");
    };

    this.ResizeFrameWidthEvent = function(event, arrParams) {
        var fData = arrParams.split(';');

        var strFrame = this.GetParamValue(fData, "f");
        if (strFrame == null) return;

        var aFrameObj = document.getElementById(strFrame);

        if (!aFrameObj) return;

        aFrameObj.style.width = this.GetParamValueDef(fData, "w", aFrameObj.style.width) + "px";
    };

    this.ResizeFrameHeightEvent = function(event, arrParams) {
        var fData = arrParams.split(';');

        var strFrame = this.GetParamValue(fData, "f");
        if (strFrame == null) return;

        var aFrameObj = document.getElementById(strFrame);

        if (!aFrameObj) return;

        aFrameObj.style.height = this.GetParamValueDef(fData, "h", aFrameObj.style.height) + "px";
    };

    this.ReturnDocumentWidth = function(event) {
        var aWidth = this.GetDocuemtWidth();

        var aString = "f=" + self.name + ";w=" + aWidth;
        this.SendMessageDest(event.source, "resizeWidth", aString, "*");
    };

    this.ReturnDocumentHeight = function(event) {
        var aHeight = this.GetDocuemtHeight();

        var aString = "f=" + self.name + ";h=" + aHeight;
        this.SendMessageDest(event.source, "resizeHeight", aString, "*");
    };

    this.GetDocuemtWidth = function() {
        var aWidth = 0;

        //if (window.document.body.leftMargin)
        //    aWidth = parseInt(window.document.body.leftMargin) + parseInt(window.document.body.rightMargin);
        return parseInt(window.document.body.scrollWidth) + aWidth;
    };

    this.GetDocuemtHeight = function() {
        var aHeight = 0;

        //if (window.document.body.topMargin)
        //    aHeight = parseInt(window.document.body.topMargin) + parseInt(window.document.body.bottomMargin);
        return parseInt(window.document.body.scrollHeight) + aHeight + 10; //add a buffer of 5 to provide a bit of padding
    };

    this.SendMessage = function(msgName, message, origin) {
        this.SendMessageDest(window.parent, msgName, message, origin);
    };
    this.SendMessageDest = function(destWindow, msgName, message, origin) {
        destWindow.postMessage("e=" + msgName + "#" + message, origin);
    };

    this.ParamExists = function(data, paramName) {
        for (var i = 0; i < data.length; i++) {
            var strData = data[i].split('=');
            if (strData[0] == paramName) return true;
        };

        return false;
    }

    this.GetParamValue = function(data, paramName) {
        for (var i = 0; i < data.length; i++) {
            var strData = data[i].split('=');
            if (strData[0] == paramName) return strData[1];
        }

        return null;
    };

    this.GetParamValueDef = function(data, paramName, defaultValue) {
        for (var i = 0; i < data.length; i++) {
            var strData = data[i].split('=');
            if (strData[0] == paramName) return strData[1];
        }

        return defaultValue;
    };

    this.FrameResize = function(autoHeight, autoWidth) {
        //If not to resize then return
        if (!this.isInitialised || (!autoHeight && !autoWidth)) return;

        var aHeight = this.GetDocuemtHeight();
        var aMsg = "f=" + self.name + ";h=" + aHeight;
        //If auto width then allow the callback for the width
        if (autoWidth) aMsg += ";autoW=true";

        this.SendMessage("resizeFrame", aMsg, "*");
    };
}

//var MessageQueue = new CSMessageQue();
//MessageQueue.Initialise();

function CSMessageManager() {
    this.MessageQueue = new CSMessageQue();
    this.MessageQueue.Initialise();

    this.AddMsgListner = function(msgName, callBack) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        this.MessageQueue.AddMsgListner(msgName, callBack);
    };

    this.RemoveMsgListner = function(msgName, callBack) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        this.MessageQueue.RemoveMsgListner(msgName, callBack);
    };

    this.AddOnMessageReceived = function(callBack) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        this.MessageQueue.AddOnMessageReceived(callBack);
    };

    this.RemoveOnMessageReceived = function(callBack) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        this.MessageQueue.RemoveOnMessageReceived(callBack);
    };
    
    this.SendMessage = function(msgName, message, origin) {
        this.SendMessageDest(window.parent, msgName, message, origin);
    };
    this.SendMessageDest = function(destWindow, msgName, message, origin) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        this.MessageQueue.SendMessageDest(destWindow, msgName, message, origin);
    };

    this.ParamExists = function(data, paramName) {
        if (!this.MessageQueue) return false;
        if (!this.MessageQueue.isInitialised) return false;

        return this.MessageQueue.ParamExists(data, paramName);
    }

    this.GetParamValue = function(data, paramName) {
        if (!this.MessageQueue) return undefined;
        if (!this.MessageQueue.isInitialised) return undefined;

        return this.MessageQueue.GetParamValue(data, paramName);
    };

    this.GetParamValueDef = function(data, paramName, defaultValue) {
        if (!this.MessageQueue) return defaultValue;
        if (!this.MessageQueue.isInitialised) return defaultValue;

        return this.MessageQueue.GetParamValueDef(data, paramName, defaultValue);
    };

    this.FrameResize = function(autoHeight, autoWidth) {
        //If not to resize then return
        if (!this.MessageQueue.isInitialised || (!autoHeight && !autoWidth)) return;

        var aHeight = this.MessageQueue.GetDocuemtHeight();
        var aMsg = "f=" + self.name + ";h=" + aHeight;
        //If auto width then allow the callback for the width
        if (autoWidth) aMsg += ";autoW=true";

        this.MessageQueue.SendMessage("resizeFrame", aMsg, "*");
    };
}

var messageManager = new CSMessageManager();
