/// <reference path="MadCapUtilities.js" />

// {{MadCap}} //////////////////////////////////////////////////////////////////
// Copyright: MadCap Software, Inc - www.madcapsoftware.com ////////////////////
////////////////////////////////////////////////////////////////////////////////
// <version>8.0.0.0</version>
////////////////////////////////////////////////////////////////////////////////

var gEmptyIcon				= null;
var gFullIcon				= null;
var gIconWidth				= 16;
var gTopicRatingIconsInit	= false;

function TopicRatingIconsInit()
{
	if ( gTopicRatingIconsInit )
	{
		return;
	}
	
	//
	
	var value	= CMCFlareStylesheet.LookupValue( "ToolbarItem", "TopicRatings", "EmptyIcon", null );

	if ( value == null )
	{
		gEmptyIcon = MCGlobals.RootFolder + MCGlobals.SkinTemplateFolder + "Images/Rating0.gif";
		gIconWidth = 16;
	}
	else
	{
		value = FMCStripCssUrl( value );
		value = decodeURIComponent( value );
		value = escape( value );
		gEmptyIcon = FMCGetSkinFolderAbsolute() + value;
	}

	value = CMCFlareStylesheet.LookupValue( "ToolbarItem", "TopicRatings", "FullIcon", null );

	if ( value == null )
	{
		gFullIcon = MCGlobals.RootFolder + MCGlobals.SkinTemplateFolder + "Images/RatingGold100.gif";
	}
	else
	{
		value = FMCStripCssUrl( value );
		value = decodeURIComponent( value );
		value = escape( value );
		gFullIcon = FMCGetSkinFolderAbsolute() + value;
	}
	
	//
	
	gTopicRatingIconsInit = true;
}

function FMCRatingIconsCalculateRating( e, iconContainer )
{
	if ( !e ) { e = window.event; }

	var x			= FMCGetMouseXRelativeTo( window, e, iconContainer );
	var imgNodes	= iconContainer.getElementsByTagName( "img" );
	var numImgNodes	= imgNodes.length;
	var iconWidth	= gIconWidth;
	var numIcons	= Math.ceil( x / iconWidth );
	numIcons = Math.max(numIcons, 1); // numIcons will be 0 if x was 0 (left most edge of the rating control).
	var rating		= numIcons * 100 / numImgNodes;
	
	return rating;
}

function FMCRatingIconsOnmousemove( e, iconContainer )
{
	TopicRatingIconsInit();
	
	//
	
	if ( !e ) { e = window.event; }

	var rating	= FMCRatingIconsCalculateRating( e, iconContainer );
	
	FMCDrawRatingIcons( rating, iconContainer );
}

function FMCClearRatingIcons( rating, iconContainer )
{
	FMCDrawRatingIcons( rating, iconContainer );
}

function FMCDrawRatingIcons( rating, iconContainer )
{
	TopicRatingIconsInit();
	
	//

	var imgNodes	= iconContainer.getElementsByTagName( "img" );
	var numImgNodes	= imgNodes.length;
	var numIcons	= Math.ceil( rating * numImgNodes / 100 );

	for ( var i = 0; i < numImgNodes; i++ )
	{
		var node	= imgNodes[i];
		
		if ( i <= numIcons - 1 )
		{
			node.src = gFullIcon;
		}
		else
		{
			node.src = gEmptyIcon;
		}
	}
}

//
//    Class CMCLiveHelpServiceClient
//

var gLiveHelpServerUrl = FMCGetFeedbackServerUrl();

function FMCGetFeedbackServerUrl()
{
	var inPreviewMode = FMCGetAttributeBool( document.documentElement, "MadCap:InPreviewMode", false );
	
	if ( inPreviewMode )
	{
		return null;
	}

	var serverUrl = FMCGetAttribute(document.documentElement, "MadCap:LiveHelpServer");
	
	if ( serverUrl == null )
	{
		return null;
	}
	
	var url			= serverUrl;
	var pos			= url.indexOf( ":" );
	var urlProtocol	= url.substring( 0, pos + 1 );
	var docProtocol	= document.location.protocol;
	
	if ( window.name != "bridge" )
	{
		if ( urlProtocol.Equals( "https:", false ) && docProtocol.Equals( "http:", false ) )
		{
			url = url.substring( pos + 1 );
			url = "http:" + url;
		}
	}
	
	if ( url.Contains( "madcapsoftware.com", false ) )
	{
		url = url + "LiveHelp/Service.LiveHelp/LiveHelpService.asmx/";
	}
	else
	{
		url = url + "Service.FeedbackExplorer/FeedbackJsonService.asmx/";
	}
	
	return url;
}

var gServiceClient = new function ()
{
    // Private member variables and functions

    var mCallbackMap = new CMCDictionary();

    var mLiveHelpScriptIndex = 0;
    var mLiveHelpService = gLiveHelpServerUrl;
    var mGetAverageRatingOnCompleteFunc = null;
    var mGetAverageRatingOnCompleteArgs = null;
    var mGetAnonymousEnabledOnCompleteFunc = null;
    var mGetAnonymousEnabledOnCompleteArgs = null;
    var mStartActivateUserOnCompleteFunc = null;
    var mStartActivateUserOnCompleteArgs = null;
    var mCheckUserStatusOnCompleteFunc = null;
    var mCheckUserStatusOnCompleteArgs = null;
    var mGetSynonymsFileOnCompleteFunc = null;
    var mGetSynonymsFileOnCompleteArgs = null;

    var mVersion = -1;
    var mPulseServer = null;
    var mPulseServerInit = false;

    function AddScriptTag(webMethodName, onCompleteFunc, nameValuePairs)
    {
        var script = document.createElement("script");
        var head = document.getElementsByTagName("head")[0];
        var scriptID = "MCLiveHelpScript_" + mLiveHelpScriptIndex++;
        var src = mLiveHelpService + webMethodName + "?";

        src += "OnComplete=" + onCompleteFunc + "&ScriptID=" + scriptID + "&UniqueID=" + (new Date()).getTime();

        if (nameValuePairs != null)
        {
            for (var i = 0, length = nameValuePairs.length; i < length; i++)
            {
                var pair = nameValuePairs[i];
                var name = pair[0];
                var value = encodeURIComponent(pair[1]);

                src += ("&" + name + "=" + value);
            }
        }

        if (window.ActiveXObject)
        {
            var ieUrlLimit = 2083;

            if (src.length > ieUrlLimit)
            {
                var diff = src.length - ieUrlLimit;
                var data = { ExceedAmount: diff };
                var ex = new CMCFeedbackException(-1, "URL limit exceeded.", data);

                throw ex;
            }
        }

        var qsLimit = 2048;
        var qsPos = src.indexOf("?")
        var qsChars = src.substring(qsPos + 1).length;

        if (qsChars > qsLimit)
        {
            var diff = qsChars - qsLimit;
            var data = { ExceedAmount: diff };
            var ex = new CMCFeedbackException(-1, "Query string limit exceeded.", data);

            throw ex;
        }

        script.id = scriptID;
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", src);

        head.appendChild(script);

        return scriptID;
    }

    // Public member functions

    this.RemoveScriptTag = function (scriptID)
    {
        function RemoveScriptTag2()
        {
            var script = document.getElementById(scriptID);

            script.parentNode.removeChild(script);
        }

        // IE bug: Need this setTimeout() or else IE will crash. This happens when removing the <script> tag after re-navigating to the same page.

        window.setTimeout(RemoveScriptTag2, 10);
    }

    this.LogTopic = function (topicID)
    {
        AddScriptTag("LogTopic", "gServiceClient.LogTopicOnComplete", [["TopicID", topicID]]);
    }

    this.LogTopicOnComplete = function (scriptID)
    {
        this.RemoveScriptTag(scriptID);
    }

    this.LogTopic2 = function (topicID, cshID, onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.LogTopic2OnComplete = function (scriptID)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(onCompleteArgs);
                }
            }

            //

            this.RemoveScriptTag(scriptID);

            this.LogTopic2OnComplete = null;
        }

        AddScriptTag("LogTopic2", "gServiceClient.LogTopic2OnComplete", [["TopicID", topicID],
																			["CSHID", cshID]]);
    }

    this.LogSearch = function (projectID, userGuid, resultCount, language, query)
    {
        AddScriptTag("LogSearch", "gServiceClient.LogSearchOnComplete", [["ProjectID", projectID],
																			["UserGuid", userGuid],
																			["ResultCount", resultCount],
																			["Language", language],
																			["Query", query]]);
    }

    this.LogSearchOnComplete = function (scriptID)
    {
        this.RemoveScriptTag(scriptID);
    }

    this.AddComment = function (topicID, userGuid, userName, subject, comment, parentCommentID)
    {
        AddScriptTag("AddComment", "gServiceClient.AddCommentOnComplete", [["TopicID", topicID],
																				["UserGuid", userGuid],
																				["Username", userName],
																				["Subject", subject],
																				["Comment", comment],
																				["ParentCommentID", parentCommentID]]);
    }

    this.AddCommentOnComplete = function (scriptID)
    {
        this.RemoveScriptTag(scriptID);
    }

    this.GetAverageRating = function (topicID, onCompleteFunc, onCompleteArgs)
    {
        mGetAverageRatingOnCompleteFunc = onCompleteFunc;
        mGetAverageRatingOnCompleteArgs = onCompleteArgs;

        AddScriptTag("GetAverageRating", "gServiceClient.GetAverageRatingOnComplete", [["TopicID", topicID]]);
    }

    this.GetAverageRatingOnComplete = function (scriptID, averageRating, ratingCount)
    {
        if (mGetAverageRatingOnCompleteFunc != null)
        {
            mGetAverageRatingOnCompleteFunc(averageRating, ratingCount, mGetAverageRatingOnCompleteArgs);
            mGetAverageRatingOnCompleteFunc = null;
            mGetAverageRatingOnCompleteArgs = null;
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.SubmitRating = function (topicID, rating, comment, onCompleteFunc, onCompleteArgs)
    {
        var scriptID = AddScriptTag("SubmitRating", "gServiceClient.SubmitRatingOnComplete", [["TopicID", topicID],
																					["Rating", rating],
																					["Comment", comment]]);

        var callbackData = { OnCompleteFunc: onCompleteFunc, OnCompleteArgs: onCompleteArgs };

        mCallbackMap.Add(scriptID, callbackData);
    }

    this.SubmitRatingOnComplete = function (scriptID)
    {
        var callbackData = mCallbackMap.GetItem(scriptID);
        var callbackFunc = callbackData.OnCompleteFunc;
        var callbackArgs = callbackData.OnCompleteArgs;

        if (callbackFunc != null)
        {
            callbackFunc(callbackArgs);

            mCallbackMap.Remove(scriptID);
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.GetTopicComments = function (topicID, userGuid, userName, onCompleteFunc, onCompleteArgs)
    {
        var scriptID = AddScriptTag("GetTopicComments", "gServiceClient.GetTopicCommentsOnComplete", [["TopicID", topicID],
																										["UserGuid", userGuid],
																										["Username", userName]]);

        var callbackData = { OnCompleteFunc: onCompleteFunc, OnCompleteArgs: onCompleteArgs };

        mCallbackMap.Add(scriptID, callbackData);
    }

    this.GetTopicCommentsOnComplete = function (scriptID, commentsXml)
    {
        var callbackData = mCallbackMap.GetItem(scriptID);
        var callbackFunc = callbackData.OnCompleteFunc;
        var callbackArgs = callbackData.OnCompleteArgs;

        if (callbackFunc != null)
        {
            callbackFunc(commentsXml, callbackArgs);

            mCallbackMap.Remove(scriptID);
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.GetAnonymousEnabled = function (projectID, onCompleteFunc, onCompleteArgs)
    {
        mGetAnonymousEnabledOnCompleteFunc = onCompleteFunc;
        mGetAnonymousEnabledOnCompleteArgs = onCompleteArgs;

        var src = mLiveHelpService + "GetAnonymousEnabled?ProjectID=" + encodeURIComponent(projectID);

        AddScriptTag("GetAnonymousEnabled", "gServiceClient.GetAnonymousEnabledOnComplete", [["ProjectID", projectID]]);
    }

    this.GetAnonymousEnabledOnComplete = function (scriptID, enabled)
    {
        if (mGetAnonymousEnabledOnCompleteFunc != null)
        {
            mGetAnonymousEnabledOnCompleteFunc(enabled, mGetAnonymousEnabledOnCompleteArgs);
            mGetAnonymousEnabledOnCompleteFunc = null;
            mGetAnonymousEnabledOnCompleteArgs = null;
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.StartActivateUser = function (xmlDoc, onCompleteFunc, onCompleteArgs)
    {
        mStartActivateUserOnCompleteFunc = onCompleteFunc;
        mStartActivateUserOnCompleteArgs = onCompleteArgs;

        var usernameNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "Username");
        var username = FMCGetAttribute(usernameNode, "Value");
        var emailAddressNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "EmailAddress");
        var emailAddress = FMCGetAttribute(emailAddressNode, "Value");
        var firstNameNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "FirstName");
        var firstName = FMCGetAttribute(firstNameNode, "Value");
        var lastNameNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "LastName");
        var lastName = FMCGetAttribute(lastNameNode, "Value");
        var countryNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "Country");
        var country = FMCGetAttribute(countryNode, "Value");
        var postalCodeNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "PostalCode");
        var postalCode = FMCGetAttribute(postalCodeNode, "Value");
        var genderNode = FMCGetChildNodeByAttribute(xmlDoc.documentElement, "Name", "Gender");
        var gender = FMCGetAttribute(genderNode, "Value");
        var uiLanguageOrder = "";

        AddScriptTag("StartActivateUser", "gServiceClient.StartActivateUserOnComplete", [["Username", username],
																							["EmailAddress", emailAddress],
																							["FirstName", firstName],
																							["LastName", lastName],
																							["Country", country],
																							["Zip", postalCode],
																							["Gender", gender],
																							["UILanguageOrder", uiLanguageOrder]]);
    }

    this.StartActivateUserOnComplete = function (scriptID, pendingGuid)
    {
        if (mStartActivateUserOnCompleteFunc != null)
        {
            mStartActivateUserOnCompleteFunc(pendingGuid, mStartActivateUserOnCompleteArgs);
            mStartActivateUserOnCompleteFunc = null;
            mStartActivateUserOnCompleteArgs = null;
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.StartActivateUser2 = function (xmlDoc, onCompleteFunc, onCompleteArgs, thisObj)
    {
        var xml = CMCXmlParser.GetOuterXml(xmlDoc);

        this.StartActivateUser2OnComplete = function (scriptID, pendingGuid)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, pendingGuid, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(pendingGuid, onCompleteArgs);
                }
            }

            //

            this.RemoveScriptTag(scriptID);

            this.StartActivateUser2OnComplete = null;
        }

        AddScriptTag("StartActivateUser2", "gServiceClient.StartActivateUser2OnComplete", [["Xml", xml]]);
    }

    this.UpdateUserProfile = function (guid, xmlDoc, onCompleteFunc, onCompleteArgs, thisObj)
    {
        var xml = CMCXmlParser.GetOuterXml(xmlDoc);

        this.UpdateUserProfileOnComplete = function (scriptID, pendingGuid)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, pendingGuid, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(pendingGuid, onCompleteArgs);
                }
            }

            //

            this.RemoveScriptTag(scriptID);

            this.UpdateUserProfileOnComplete = null;
        }

        AddScriptTag("UpdateUserProfile", "gServiceClient.UpdateUserProfileOnComplete", [["Guid", guid],
																							["Xml", xml]]);
    }

    this.GetUserProfile = function (guid, onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.GetUserProfileOnComplete = function (scriptID, userProfileXml)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                    onCompleteFunc.call(thisObj, userProfileXml, onCompleteArgs);
                else
                    onCompleteFunc(userProfileXml, onCompleteArgs);
            }

            //

            this.RemoveScriptTag(scriptID);

            this.GetUserProfileOnComplete = null;
        }

        AddScriptTag("GetUserProfile", "gServiceClient.GetUserProfileOnComplete", [["Guid", guid]]);
    }

    this.CheckUserStatus = function (pendingGuid, onCompleteFunc, onCompleteArgs)
    {
        mCheckUserStatusOnCompleteFunc = onCompleteFunc;
        mCheckUserStatusOnCompleteArgs = onCompleteArgs;

        AddScriptTag("CheckUserStatus", "gServiceClient.CheckUserStatusOnComplete", [["PendingGuid", pendingGuid]]);
    }

    this.CheckUserStatusOnComplete = function (scriptID, status)
    {
        if (mCheckUserStatusOnCompleteFunc != null)
        {
            var func = mCheckUserStatusOnCompleteFunc;
            var args = mCheckUserStatusOnCompleteArgs;
            mCheckUserStatusOnCompleteFunc = null;
            mCheckUserStatusOnCompleteArgs = null;

            func(status, args);
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.GetSynonymsFile = function (projectID, updatedSince, onCompleteFunc, onCompleteArgs)
    {
        mGetSynonymsFileOnCompleteFunc = onCompleteFunc;
        mGetSynonymsFileOnCompleteArgs = onCompleteArgs;

        AddScriptTag("GetSynonymsFile", "gServiceClient.GetSynonymsFileOnComplete", [["ProjectID", projectID],
																						["UpdatedSince", updatedSince]]);
    }

    this.GetSynonymsFileOnComplete = function (scriptID, synonymsXml)
    {
        if (mGetSynonymsFileOnCompleteFunc != null)
        {
            mGetSynonymsFileOnCompleteFunc(synonymsXml, mGetSynonymsFileOnCompleteArgs);
            mGetSynonymsFileOnCompleteFunc = null;
            mGetSynonymsFileOnCompleteArgs = null;
        }

        //

        this.RemoveScriptTag(scriptID);
    }

    this.GetVersion = function (onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.GetVersionOnComplete = function (scriptID, version)
        {
            if (version == null)
            {
                mVersion = 1;
            }
            else
            {
                mVersion = version;
            }

            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, mVersion, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(mVersion, onCompleteArgs);
                }
            }

            //

            if (scriptID != null)
            {
                this.RemoveScriptTag(scriptID);
            }

            this.GetVersionOnComplete = null;
        }

        if (mVersion == -1)
        {
            AddScriptTag("GetVersion", "gServiceClient.GetVersionOnComplete");
        }
        else
        {
            this.GetVersionOnComplete(null, mVersion);
        }
    }

    this.GetPulseServer = function (onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.GetPulseServerOnComplete = function (scriptID, server)
        {
            mPulseServer = server;
            mPulseServerInit = true;

            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, mPulseServer, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(mPulseServer, onCompleteArgs);
                }
            }

            //

            if (scriptID != null)
            {
                this.RemoveScriptTag(scriptID);
            }

            this.GetPulseServerOnComplete = null;
        }

        if (!mPulseServerInit)
        {
            AddScriptTag("GetPulseServer", "gServiceClient.GetPulseServerOnComplete");
        }
        else
        {
            this.GetPulseServerOnComplete(null, mPulseServer);
        }
    }

    this.GetPulseStreamID = function (topicID, onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.GetPulseStreamIDOnComplete = function (scriptID, streamID)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, streamID, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(streamID, onCompleteArgs);
                }
            }

            //

            if (scriptID != null)
            {
                this.RemoveScriptTag(scriptID);
            }

            this.GetPulseStreamIDOnComplete = null;
        }

        AddScriptTag("GetPulseStreamID", "gServiceClient.GetPulseStreamIDOnComplete", [["TopicID", topicID]]);
    }

    this.GetTopicPathByStreamID = function (streamID, onCompleteFunc, onCompleteArgs, thisObj)
    {
        this.GetTopicPathByStreamIDOnComplete = function (scriptID, topicPath)
        {
            if (onCompleteFunc != null)
            {
                if (thisObj != null)
                {
                    onCompleteFunc.call(thisObj, topicPath, onCompleteArgs);
                }
                else
                {
                    onCompleteFunc(topicPath, onCompleteArgs);
                }
            }

            //

            if (scriptID != null)
            {
                this.RemoveScriptTag(scriptID);
            }

            this.GetTopicPathByStreamIDOnComplete = null;
        }

        AddScriptTag("GetTopicPathByStreamID", "gServiceClient.GetTopicPathByStreamIDOnComplete", [["StreamID", streamID]]);
    }
}

//
//    End class CMCLiveHelpServiceClient
//

//
//    Class CMCFeedbackException
//

function CMCFeedbackException( number, message, data )
{
	CMCException.call( this, number, message );

	// Public properties

	this.Data = data;
}

CMCFeedbackException.prototype = new CMCException();
CMCFeedbackException.prototype.constructor = CMCFeedbackException;
CMCFeedbackException.prototype.base = CMCException.prototype;

//
//    End class CMCFeedbackException
//
