<!--
/******************************************************************************
$Workfile: WebServices.js $
$Revision: 3 $
$Author: Tkostich $

Common web services javascript objects and methods.

Copyright (c) 2006 OSIsoft, Inc. All rights reserved.

Unpublished - rights reserved under the copyright law of the United States.

USE OF A COPYRIGHT NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION 
OR DISCLOSURE. THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE SECRETS 
OF OSISOFT, INC. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR 
EXPRESS WRITTEN PERMISSION OF OSISOFT, INC.

RESTRICTED RIGHTS LEGEND
Use, duplication, or disclosure by the Government is subject to restrictions as 
set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer 
Software clause at DFARS 252.227.7013

OSIsoft, Inc.
777 Davis Street, Suite 250, San Leandro CA 94577
*******************************************************************************/


// Our custom collection definition
function RtService() {
	this.available = false;			// Indicates availability for callService()
	this.url = "";					// Includes "?WSDL"
	this.friendlyName = "";			// Web service friendly name "TimeRangeWS"
	this.WSDL = null;				// object
	this.reuseConnection = null;	// For the useService() call
	this.serviceAvailableCallbacks = new Array();
}

// RtWebParts call the RtWebService_Add() function which uses the next array var
var RtServices = new Array(); // Variables created with the var keyword cannot be deleted

// Hooks up our collection of web services to the webservices behavior
function RtWebService_UseServices() {
	// Hook up our array of custom objects to the webservices behavior object for consumer access
	RtWebService.RtServices = RtServices;
	
	// Initialize our web services
	var service;
	for(var serviceName in RtWebService.RtServices) {
		service = RtWebService.RtServices[serviceName];
		if( service.reuseConnection != null && typeof(service.reuseConnection) == "boolean" )
			RtWebService.useService(service.url + "?WSDL", service.friendlyName, 
									RtWebService.createUseOptions(service.reuseConnection));
		else
			RtWebService.useService(service.url + "?WSDL", service.friendlyName);
		
	}
}
window.attachEvent("onload", RtWebService_UseServices); // Add our function to the onLoad() chain

// Queues a web service name and URL to be used with the Microsoft webservice.htc behavior
// Both wsAvailableCallback and reuseConnection are optional parameters
//
// reuseConnection: A Boolean that specifies the mode of remote method invocation.
//   false  Default. Remote method invocations are processed in parallel, and if SSL authentication is required by the Web Service, then authentication is required in order to process each call to the Web Service.
//   true   Remote method invocations are processed sequentially, and the data provided for SSL authentication is retained for each call to the Web Service. 
function RtWebService_Add(wsName, wsURL, wsAvailableCallback, reuseConnection) {
	validCallback = false;
	alreadyAdded = false;
	
	if( typeof(wsAvailableCallback) != "undefined" && 
		typeof(wsAvailableCallback) != "function" )
		throw("[RtWebService_Add] ERROR: Optional parameter 'wsAvailableCallback' is not a function. "
			+ "It is a " + typeof(wsAvailableCallback) );
	else if( typeof(wsAvailableCallback) == "function" )
		validCallback = true;
	
	handle = eval("RtServices." + wsName);
	if( typeof(handle) == "undefined" ) {
		RtServices[wsName] = new RtService();
		handle = eval("RtServices." + wsName);
	} else {
		alreadyAdded = true;
	}	
	
	if( alreadyAdded && typeof(wsURL) != "undefined" && wsURL != null &&
		handle.url != wsURL )
		throw("[RtWebService_Add] ERROR: '" + wsName 
			+ "' has already been defined with a serviceUrl of " + handle.url);

	if( alreadyAdded && typeof(reuseConnection) != "undefined" && reuseConnection != null &&
	    handle.reuseConnection != null && handle.reuseConnection != reuseConnection )
		throw("[RtWebService_Add] ERROR: '" + wsName 
			+ "' has already been defined with reuseConnection = " + handle.reuseConnection);
	
	handle.friendlyName = wsName;
	handle.url = wsURL;	
	if( validCallback ) {
		ctr = handle.serviceAvailableCallbacks.length;
		handle.serviceAvailableCallbacks[ctr] = wsAvailableCallback;
	}
	if( typeof(reuseConnection) != "undefined" && reuseConnection != null )
		handle.reuseConnection = reuseConnection;
}

// Event handler for the webservice behavior event "onserviceavailable"
// Fires asynchronously after each useService() call
function RtWebService_OnServiceAvailable() {
	try
	{
		// Misleading purpose of "userName" in this context. Why Microsoft chose to 
		// overload the meaning of this property is beyond me. It's usually associated
		// with a real user name for web services requiring authentication which is 
		// also supported by the webservice behavior
		var webServiceName = event.userName; // In this context, this is the web service friendly name
				
		// Add this service to our custom collection if it doesn't already exist. Someone may have
		// accessed the RtWebService.useService directly instead of calling our RtWebService_Add()
		if( typeof(RtWebService.RtServices[webServiceName]) == "undefined" ) {
			RtWebService.RtServices[webServiceName] = new RtService();
		}
		// Store the state of the web service
		RtWebService.RtServices[webServiceName].available    = event.serviceAvailable;
		RtWebService.RtServices[webServiceName].url          = event.serviceUrl;
		RtWebService.RtServices[webServiceName].friendlyName = webServiceName;
		RtWebService.RtServices[webServiceName].WSDL         = event.WSDL;
		
		/* DEBUG
		alert(RtWebService.RtServices[webServiceName].friendlyName + 
		((RtWebService.RtServices[webServiceName].available) ? " is " : " is NOT ") + "available");
		*/
		
		// Fire any serviceAvailableCallbacks. 
		// There can easily be more than one consumer for each web service
		for(var i=0; i<RtWebService.RtServices[webServiceName].serviceAvailableCallbacks.length; i++) {
			try
			{
				(RtWebService.RtServices[webServiceName].serviceAvailableCallbacks[i])(RtWebService.RtServices[webServiceName]);
			}
			catch(ex)
			{
				// Better safe than sorry!
			}
		}
	}
	catch(ex)
	{
		alert("RtWebService_OnServiceAvailable(): " + ex.message);
	}
}

// Event handler for the webservice behavior event "onresult"
// Only fires if someone invokes callService asynchronously and does not supply a callback handler
function RtWebService_OnResult() {
	var msg = "A web service was called without a function callback and returned the following:\n\n";
	if( event.result.error ) // boolean
	{
		var faultCode   = event.result.errorDetail.code;
		var faultString = event.result.errorDetail.string;
		msg += "Error Code = " + faultCode + "\n\nError Text = " + faultString;
	} else {
		msg += event.result.raw.xml;
	}
	alert(msg);
}
//-->