
    // Application ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Application = Class.create();
    Application.prototype =
    {
        sVersion : null,
        sPath : null,
        
        initialize : function()
        {
            this.sVersion = "?";
            this.sPath = "";
        },
        
        getVersion : function()
        {
            return this.sVersion;
        },
        
        getPath : function()
        {
            return this.sPath;
        },
        
        getServerName : function()
        {
            return self.location.hostname;
        },
        
        getServerProtocol : function()
        {
            return self.location.protocol;
        },
        
        getBaseURI : function()
        {
            return Application.getServerProtocol() + "//" + Application.getServerName();
        },
        
        isHTTPS : function()
        {
            return Application.getServerProtocol().toLowerCase() == "https:";
        }
    };
    
    Application.oInstance = null;
    Application.getInstance = function(p_sString)
    {
        if(Application.oInstance == null) {
            Application.oInstance = new Application();
        }
        
        return Application.oInstance;
    };

    // Static methods
    {
        Application.getVersion = function() {
            return Application.getInstance().getVersion();
        };
        
        Application.getPath = function() {
            return Application.getInstance().getPath();
        };
        
        Application.getServerName = function() {
            return Application.getInstance().getServerName();
        };
        
        Application.getServerProtocol = function() {
            return Application.getInstance().getServerProtocol();
        };
        
        Application.getBaseURI = function() {
            return Application.getInstance().getBaseURI();
        };
        
        Application.isHTTPS = function() {
            return Application.getInstance().isHTTPS();
        };
    }
    
    // User ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    User = Class.create();
    User.prototype =
    {
        sId : 0,
        sAvatar : "",
        sExternalAvatar : "",
        sName : "",
        sUserType : 0,
        sAccount : 0,
        sKbaId : 0,
        sAccountTable : "",
        sCurrencyCode : "CAD",
        sContactUnicity : "email",
        sCustomSignature : "",
        sMonthlyFee : new Array(),
        
        initialize : function()
        {
            
        },
        
        setId : function(p_sId)
        {
            this.sId = p_sId;
        },
        
        getId : function()
        {
            return this.sId;
        },
        
        setKbaId : function(p_sKbaId)
        {
            this.sKbaId = p_sKbaId;
        },
        
        getKbaId : function()
        {
            return this.sKbaId;
        },
        
        setAvatar : function(p_sAvatar)
        {
            this.sAvatar = p_sAvatar;
        },

        getAvatar : function()
        {
            return this.sAvatar;
        },
        
        setExternalAvatar : function(p_sExternalAvatar)
        {
            this.sExternalAvatar = p_sExternalAvatar;
        },

        getExternalAvatar : function()
        {
            return this.sExternalAvatar;
        },
        
        setName : function(p_sName)
        {
            this.sName = p_sName;
        },

        getName : function()
        {
            return this.sName;
        },
        
        setUserType : function(p_sUserType)
        {
            this.sUserType = p_sUserType;
        },

        getUserType : function()
        {
            return this.sUserType;
        },
        
        setAccount : function(p_sAccount)
        {
            this.sAccount = p_sAccount;
        },

        getAccount : function()
        {
            return this.sAccount;
        },
        
        setAccountTable : function(p_sAccountTable)
        {
            this.sAccountTable = p_sAccountTable;
        },

        getAccountTable : function()
        {
            return this.sAccountTable;
        },
        
        setCurrencyCode : function(p_sCurrencyCode)
        {
            this.sCurrencyCode = p_sCurrencyCode;
        },

        getCurrencyCode : function()
        {
            return this.sCurrencyCode;
        },
        
        setContactUnicity : function(p_sContactUnicity)
        {
            this.sContactUnicity = p_sContactUnicity;
        },

        getContactUnicity : function()
        {
            return this.sContactUnicity;
        },
        
        setCustomSignature : function(p_sCustomSignature)
        {
            this.sCustomSignature = p_sCustomSignature;
        },

        getCustomSignature : function()
        {
            return this.sCustomSignature;
        },
        
        setMonthlyFee : function(p_sMonthlyFee)
        {
            this.sMonthlyFee[this.sMonthlyFee.length] = p_sMonthlyFee;
        },

        getMonthlyFee : function()
        {
            return this.sMonthlyFee;
        },
        
        hasMonthlyFee : function(p_sMonthlyFee)
        {
            return this.sMonthlyFee.in_array(p_sMonthlyFee);
        }
    };

    User.oInstance = null;
    User.getInstance = function(p_sString)
    {
        if(User.oInstance == null)
        {
            User.oInstance = new User();
        }

        return User.oInstance;
    };

    // Static methods
    {
        User.setId = function(p_sId)
        {
            User.getInstance().setId(p_sId);
        };

        User.getId = function()
        {
            return User.getInstance().getId();
        };
        
        User.setKbaId = function(p_sKbaId)
        {
            User.getInstance().setKbaId(p_sKbaId);
        };

        User.getKbaId = function()
        {
            return User.getInstance().getKbaId();
        };
        
        User.setExternalAvatar = function(p_sExternalAvatar)
        {
            User.getInstance().setExternalAvatar(p_sExternalAvatar);
        };

        User.getExternalAvatar = function()
        {
            return User.getInstance().getExternalAvatar();
        };
        
        User.setAvatar = function(p_sAvatar)
        {
            User.getInstance().setAvatar(p_sAvatar);
        };

        User.getAvatar = function()
        {
            return User.getInstance().getAvatar();
        };
        
        User.setName = function(p_sName)
        {
            User.getInstance().setName(p_sName);
        };

        User.getName = function()
        {
            return User.getInstance().getName();
        };
        
        User.setUserType = function(p_sUserType)
        {
            User.getInstance().setUserType(p_sUserType);
        };

        User.getUserType = function()
        {
            return User.getInstance().getUserType();
        };
        
        User.setAccount = function(p_sAccount)
        {
            User.getInstance().setAccount(p_sAccount);
        };

        User.getAccount = function()
        {
            return User.getInstance().getAccount();
        };
        
        User.setCurrencyCode = function(p_sCurrencyCode)
        {
            User.getInstance().setCurrencyCode(p_sCurrencyCode);
        };

        User.getCurrencyCode = function()
        {
            return User.getInstance().getCurrencyCode();
        };
        
        User.setContactUnicity = function(p_sContactUnicity)
        {
            User.getInstance().setContactUnicity(p_sContactUnicity);
        };

        User.getContactUnicity = function()
        {
            return User.getInstance().getContactUnicity();
        };
        
        User.setCustomSignature = function(p_sCustomSignature)
        {
            User.getInstance().setCustomSignature(p_sCustomSignature);
        };

        User.getCustomSignature = function()
        {
            return User.getInstance().getCustomSignature();
        };
        
        User.setMonthlyFee = function(p_sMonthlyFee)
        {
            User.getInstance().setMonthlyFee(p_sMonthlyFee);
        };

        User.getMonthlyFee = function()
        {
            return User.getInstance().getMonthlyFee();
        };
        
        User.hasMonthlyFee = function(p_sMonthlyFee)
        {
            return User.getInstance().hasMonthlyFee(p_sMonthlyFee);
        };
    }
    
    // KeybookConfiguration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeybookConfiguration = Class.create();
    KeybookConfiguration.prototype =
    {
        sTps : 0,
        sTvq : 0,
        
        initialize : function()
        {
            
        },
        
        setTps : function(p_sTps)
        {
            this.sTps = p_sTps;
        },
        
        getTps : function()
        {
            return this.sTps;
        },
        
        setTvq : function(p_sTvq)
        {
            this.sTvq = p_sTvq;
        },

        getTvq : function(p_date)
        {
            var sTvq = this.sTvq;
            if(p_date && p_date != "") {
                p_date.replace(/\/\./g, "-");
                var oDateParts = p_date.split("-");
                var iYear = parseInt(oDateParts[0]);
                if(iYear < 2011) {
                    sTvq = 0.075;
                }
                else if(iYear < 2012) {
                    sTvq = 0.085;
                }
            }
            return sTvq;
        }
    };

    KeybookConfiguration.oInstance = null;
    KeybookConfiguration.getInstance = function(p_sString)
    {
        if(KeybookConfiguration.oInstance == null)
        {
            KeybookConfiguration.oInstance = new KeybookConfiguration();
        }

        return KeybookConfiguration.oInstance;
    };

    // Static methods
    {
        KeybookConfiguration.setTps = function(p_sTps)
        {
            KeybookConfiguration.getInstance().setTps(p_sTps);
        };

        KeybookConfiguration.getTps = function()
        {
            return KeybookConfiguration.getInstance().getTps();
        };
        
        KeybookConfiguration.setTvq = function(p_sTvq)
        {
            KeybookConfiguration.getInstance().setTvq(p_sTvq);
        };

        KeybookConfiguration.getTvq = function(p_date)
        {
            return KeybookConfiguration.getInstance().getTvq(p_date);
        };
    }

    // Localization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Localization = Class.create();
    Localization.prototype =
    {
        sLanguage : "fr_FR",
        aTranslations : null,

        initialize : function()
        {
            this.aTranslations = [];
        },

        setLanguage : function(p_sLanguage)
        {
            this.sLanguage = p_sLanguage;
        },

        getLanguage : function()
        {
            return this.sLanguage;
        },

        setTranslation : function(p_sString, p_sTranslation)
        {
            this.aTranslations[p_sString] = p_sTranslation;
        },

        getTranslation : function(p_sString)
        {
            return this.aTranslations[p_sString];
        }
    };

    Localization.oInstance = null;
    Localization.getInstance = function(p_sString)
    {
        if(Localization.oInstance == null)
        {
            Localization.oInstance = new Localization();
        }

        return Localization.oInstance;
    };

    // Static methods
    {
        Localization.setLanguage = function(p_sLanguage)
        {
            if(!bChanged || confirmChangesLoss())
            {
                window.location.href = setURLParameter(window.location.href, "language", p_sLanguage);
            }
        };

        Localization.getLanguage = function(p_sString)
        {
            return Localization.getInstance().getLanguage();
        };

        Localization.setTranslation = function(p_sString, p_sTranslation)
        {
            Localization.getInstance().setTranslation(p_sString, p_sTranslation);
        };

        Localization.getTranslation = function(p_sString)
        {
            return Localization.getInstance().getTranslation(p_sString);
        };

        // Load some strings from a XML element.
        Localization.load = function(xLocalization)
        {
            var aStrings = xLocalization.getElementsByTagName("string");
            var aTranslations;
            var iTranslationIndex;
            var xTranslation;
            var sTranslation
            var iIndex;
            for(iIndex = 0; iIndex < aStrings.length; ++iIndex)
            {
                // Select the appropiate translation, according to the current language.
                aTranslations = aStrings[iIndex].getElementsByTagName("translation");
                for(iTranslationIndex = 0; iTranslationIndex < aTranslations.length; ++iTranslationIndex)
                {
                    xTranslation = aTranslations[iTranslationIndex];
                    sTranslation = "";//"?" + aStrings[iIndex].getAttribute("id") + "?";
                    if(xTranslation.getAttribute("language") == Localization.getLanguage())
                    {
                        if(xTranslation["firstChild"] && xTranslation.firstChild.nodeType == 3)
                        {
                            sTranslation = xTranslation.firstChild.nodeValue;
                            break;
                        }
                    }
                }

                Localization.setTranslation(aStrings[iIndex].getAttribute("id"), sTranslation);
            }
        };
    }

	// var oLanguageDialog = null;
	// Event.observe(window, 'load', function()
	// {
		// var oLanguageItem = $('languageMenuItem');
		// if(oLanguageItem)
		// {
			// oLanguageDialog = new Dialog(oLanguageItem.down("a"),
			// {
			// });
		// }
	// });

	function hideLanguageDialog()
	{
		// if(oLanguageDialog)
		// {
			// oLanguageDialog.close();
		// }
	}



    // Change detection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
        bChanged = false;

        function notifyChange()
        {
            bChanged = true;
        }

        function confirmChangesLoss()
        {
            return confirm(Localization.getTranslation("message.confirmChangesLoss"));
        }
    }


    // Navigation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
        function go(p_sURL)
        {
            try
            {
                if(!bChanged || confirmChangesLoss())
                {
                    window.location.href = p_sURL;
                }
            } catch(err) {}
        }

        function getURLParameter(p_sURL, p_sParameter)
        {
            var r_sValue = null;
            var oPattern = new RegExp("[\\?&]" + p_sParameter + "=([^&#]*)");
            var aResults = oPattern.exec(p_sURL);
            if(aResults != null)
            {
                r_sValue  = unescape(aResults[1]);
            }
            return r_sValue;
        }

        function setURLParameter(p_sURL, p_sParameter, p_sValue)
        {
            var r_sURL = p_sURL;

            // First, remove the parameter if it exists yet.
            if(getURLParameter(p_sURL, p_sParameter) != null)
            {
                r_sURL = removeURLParameter(p_sURL, p_sParameter);
            }

            // If the URL contains parameters, add the parameter after '&'
            if(r_sURL.indexOf("?") > -1)
            {
                r_sURL += "&";
            }
            else
            {
                // If the URL does not contain any parameter, add the parameter after '?'
                r_sURL += "?";
            }

            r_sURL += p_sParameter + "=" + p_sValue;

            return r_sURL;
        }

        function removeURLParameter(p_sURL, p_sParameter)
        {
            var r_sURL = p_sURL;
            if(getURLParameter(p_sURL, p_sParameter) != null)
            {
                var iIndex = p_sURL.indexOf("?");
                var r_sURL = p_sURL.substring(0, iIndex);
                if(iIndex > -1)
                {
                    aParameters = p_sURL.substring(iIndex + 1).split("&");
                    var sParameter;
                    var bFirstParameter = true;
                    for(iIndex = 0; iIndex < aParameters.length; ++iIndex)
                    {
                        sParameter = aParameters[iIndex];
                        if(sParameter.split("=")[0] != p_sParameter)
                        {
                            if(bFirstParameter)
                            {
                                r_sURL += "?";
                                bFirstParameter = false;
                            }
                            else
                            {
                                r_sURL += "&";
                            }
                            r_sURL += sParameter;
                        }
                    }
                }
            }

            return r_sURL;
        }
    }
    
    
    
    // Validation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    {
        function setClassName(p_element, p_className) {
            var r_className = '';
            var s_className = p_element.className;
            var a_className = s_className.split(' ');
            
            var s_already = false;
            for(iIndex = 0; iIndex < a_className.length; iIndex++) {
                if(a_className[iIndex] == p_className) {
                    s_already = true;
                }
            }
            
            if(!s_already) {
                a_className[a_className.length] = p_className;
            }
            
            r_className = a_className.join(' ');
            
            return r_className;
        }
        
        function removeClassName(p_element, p_className) {
            var r_className = '';
            var t_className = Array();
            var s_className = p_element.className;
            var a_className = s_className.split(' ');
            
            for(iIndex = 0; iIndex < a_className.length; iIndex++) {
                if(a_className[iIndex] != p_className) {
                    t_className[t_className.length] = a_className[iIndex];
                }
            }
            
            r_className = t_className.join(' ');
            
            return r_className;
        }
    }



	// Authentication ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	// var oLogInDialog = null;
	// Event.observe(window, 'load', function()
	// {
		// var oLogInItem = $('logInMenuItem');
		// if(oLogInItem)
		// {
			// oLogInDialog = new Dialog(oLogInItem.down("a"),
			// {
			// });
		// }
	// });

	function setUpLogInDialogFieldsListeners()
	{
		var logInOnKeyEnter = function(p_oEvent)
        {
            oKeyEvent = new KeyEvent(KeyEvent.Type.PRESSED, p_oEvent);
            if(oKeyEvent.getCode() == KeyEvent.ENTER)
            {
                logIn();
            }
        };

		$("logInDialogUserField").observe("keydown", logInOnKeyEnter);
		$("logInDialogPasswordField").observe("keydown", logInOnKeyEnter);
	}

	function showLogInDialog()
	{
		if(oLogInDialog)
		{
			oLogInDialog.open();
			$("logInDialogUserField").focus();
		}
	}

	function hideLogInDialog()
	{
		if(oLogInDialog)
		{
			oLogInDialog.close();
		}
	}

	function logIn()
	{
        var oLogInDialogUserField     = $('logInDialogUserField');
        var oLogInDialogPasswordField = $('logInDialogPasswordField');
        
        if (oLogInDialogUserField.value != "" && oLogInDialogPasswordField.value != "")
        {
            $('logInForm').submit();
        }
	}


	function logOut()
	{
	    go("/logOut.php");
	}

