/*###################################################################

Revision history:

Date      | By | Description
----------+----+------------------------------------------
14-Mar-07   RP   Created.

####################################################################*/

//####################################################################
// These variables can safely be modified by client scripts as required
//####################################################################

// if true, helpful debug alerts will be be displayed.
var DebugAlert = false; 

// notifies every time a web service is executed. DebugAlert must be true.
var DebugAlertOnWebServiceExec = false; 

// notifies what parameters are used for a web service. Both above variables must be true.
var DebugAlertShowParamsOnExec = false;

// if true, alerts will be sent to a DIV element rather than the alert box.
var UseDebugPanel = true;

// If true, then no style data will be allocated to the DebugPanel. UseDebugPanel must be set to true.
// This means the client should define CSS class definitions for div.DebugPanel, div.DebugEntry, div.DebugHeading
var DebugPanelUseCustomStyle = false; 



//####################################################################
// ChartingWebService definition and methods
//####################################################################
function ChartingWebService()
{
	 this.WebServiceUrl ='http://'+serverName+'/WebServices/charting.asmx';
}
function TNXWebService()
{
	 this.WebServiceUrl ='http://'+serverName+'/WebServices/BusinessObjLoader.asmx';
}
function PortfolioWebService()
{
	 this.WebServiceUrl ='http://'+serverName+'/WebServices/BusinessObjLoader.asmx';
}
function LoadSectorQs(r)
{
 	LoadOptionList(r, 'qsSectorsDD', 'Sectors');
}
function LoadDomicilesQs(r)
{
 	LoadOptionList(r, 'qsDomicileDD', 'Domiciles');
}
function LoadManagersQs(r)
{
 	LoadOptionList(r, 'qsManagerDD', 'Managers');
}

function LoadFilterBusObjectLoad(busCollObjName,univCode,loadMethod,param,nameProperty,codeProperty,filter,sort)
{
var pws = new PortfolioWebService();
if(busCollObjName=="Sectors")
pws.LoadFilterBusObjects(LoadSectorQs,busCollObjName,univCode,loadMethod,param,nameProperty,codeProperty,filter,sort);
if(busCollObjName=="Domiciles")
pws.LoadBusObjAdoQS(LoadDomicilesQs,busCollObjName,univCode,nameProperty,codeProperty,filter,sort);
if(busCollObjName=="Managers")
pws.LoadFilterBusObjects(LoadManagersQs,busCollObjName,univCode,loadMethod,param,nameProperty,codeProperty,filter,sort);
}

function CalDayLightTimeLoad()
{
var pws = new PortfolioWebService();
pws.CalDayLightTime(LoadDayLightData);
}

function LoadSectorByAssetClassLoad(assetClassCode,univCode,nameProperty,codeProperty,filter,sort)
{
var pws = new PortfolioWebService();
pws.LoadSectorByAssetClassQs(LoadSectorQs,assetClassCode,univCode,nameProperty,codeProperty,filter,sort);
}

function AddPortfolioFundDisplay(portfolioId, userId, univCode, typeCode)
{
var pws = new PortfolioWebService();
pws.AddPortfolioFund(UserCount,portfolioId, userId, univCode, typeCode);
}

function PortfolioUpdateFundList(typecode,pDate,quantity,fundcurrency,currency,costV,pCost,rowGuid,port,userId)
{
var pws = new PortfolioWebService();
pws.UpdatePortfolioFund(UserCount,typecode,pDate,quantity,fundcurrency,currency,costV,pCost,rowGuid,port,userId);
}

 
function CashUpdateList(typecode,quantity,fundcurrency,currency,AccType,name,port,userId)
{
var pws = new PortfolioWebService();
pws.UpdateCash(UserCount,typecode,quantity,fundcurrency,currency,AccType,name,port,userId);
}

function AddPortfolioFundDisplay(portfolioId, userId, univCode, typeCode)
{
var pws = new PortfolioWebService();
pws.AddPortfolioFund(UserCount,portfolioId, userId, univCode, typeCode);
}

function RemovePortfolioFundDisplay(portfolioId, userId,typeCode)
{
var pws = new PortfolioWebService();
pws.RemovePortfolioFund(UserCount,portfolioId, userId, typeCode);
}

function AddWatchlistFundDisplay(userId, univCode, typeCode,SiteCode)
{
var pws = new PortfolioWebService();
pws.AddWatchlistFund(UserCount,userId, univCode, typeCode,SiteCode);
}

function RemoveWatchlistFundDisplay(userId, univCode, typeCode,SiteCode)
{
var pws = new PortfolioWebService();
pws.RemoveWatchlistFund(UserCount,userId, univCode, typeCode,SiteCode);
}

function CheckLoginUserDetails(email,password)
{
var pws = new PortfolioWebService();
pws.CheckUserLogIn(UserDetails,email, password);
}

function UserDetails(r)
{
    if(r!="0")
    {
		if(allowPop && allowPop == "true")
		{
			window.open('http://www.trustnet.com/?uId='+r,'_blank');
		}
	   else
	   {
			window.location.href = "/?uId="+r;
	   }
    }else
    {
        alert("!Invalid UserDetails");
    }
}

function FundByType(typeCode)
{
var pws = new PortfolioWebService();
pws.LoadFundByType(SetBasketVisibility,typeCode);
}

function CheckTypeCodeInPortfolio(portfolioId, typeCode)
{
var pws = new PortfolioWebService();
pws.IsTypeCodeExistInPortfolio(IsTypeCodeInPortfolio,portfolioId, typeCode);
}


function PortfolioByUserId(userId)
{
var pws = new PortfolioWebService();
pws.LoadPortfolioByUserId(PopulateBasketPortfolio,userId);
}

function WatchlistByUserId(userId)
{
var pws = new PortfolioWebService();
pws.LoadWatchlistByUserId(LoadHiddenWatchList,userId);
}

function FundByTypeCode(typeCode)
{
var pws = new PortfolioWebService();
pws.LoadFundByTypes(SetProdSearchBaseket,typeCode);
 
}

function UpdateUserCookieByIPinDB(userId,cookieName,cookieValue)
{
	var pws = new PortfolioWebService();
	pws.UpdateUserCookieDB(UpdateUserCookieByIPFn,userId,cookieName,cookieValue);
}

function SectorsByAssetClassQS(universe, filter)
{
    var pws = new PortfolioWebService();
    pws.LoadSectorsByAssetClassQS(PopulateSectors,universe, filter);

}

function AssetClassByUniverseQS(universe )
{
    var pws = new PortfolioWebService();
    pws.LoadAssetClassByUniverseQS(PopulateAssetClass,universe );

}

function ManagersByUniverseQS(universe )
{
    var pws = new PortfolioWebService();
    pws.LoadManagersByUniverseQS(PopulateManager,universe);

}

function DomicilesByUniverseQS(universe )
{
    var pws = new PortfolioWebService();
    pws.LoadDomicilesByUniverseQS(PopulateDomiciles,universe );

}

function GeoareaByUniverseQS(universe )
{
    var pws = new PortfolioWebService();
    pws.LoadGeoareaByUniverseQS(PopulateGeoarea,universe );

}

function VCTQSObjects(delegate,universe, filter)
{
    var pws = new PortfolioWebService();
    pws.LoadVCTQSObjects(delegate,universe, filter);

}

function SPSFObjects(delegate,universe, filter)
{
    var pws = new PortfolioWebService();
    pws.LoadSPSFManagers(delegate,universe, filter);
}



function UserCount(r)
{   
   return r;
}

function ManagersByUniverseSF(universe)
{
    var pws = new PortfolioWebService();
    pws.LoadManagersByUniverseSF(PopulateManagerSF,universe);

}


PortfolioWebService.prototype.LoadSectorsByAssetClassQS=function(delegateFunc,universe, filter)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);
    p.Add('assetClassName',filter);
    this.Invoke('LoadSectorsByAssetClassQS', p,delegateFunc);
}

PortfolioWebService.prototype.LoadAssetClassByUniverseQS=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);    
    this.Invoke('LoadAssetClassByUniverseQS', p,delegateFunc);
}

TNXWebService.prototype.LoadSectorsByUniverse=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('busCollObjName','Sector');
    p.Add('univCode',universe);
    p.Add('nameProperty','NameLong');
    p.Add('codeProperty','SectorClassCode');
    p.Add('filter','');
    p.Add('sort','NameLong');
    this.Invoke('LoadBusObjAdo', p,delegateFunc);
}


PortfolioWebService.prototype.UpdatePollChoice=function(delegateFunc,pollId,pollChoiceId)
{
    var p = new WSParameters();
    p.Add('pollId',pollId);
    p.Add('pollChoiceId',pollChoiceId);   
    this.Invoke('UpdatePollChoice', p,delegateFunc);
}

PortfolioWebService.prototype.LoadManagersByUniverseQS=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);
    p.Add('includeAll',false);
    this.Invoke('LoadManagersByUniverseQS', p,delegateFunc);
}

PortfolioWebService.prototype.LoadDomicilesByUniverseQS=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);    
    this.Invoke('LoadDomicilesByUniverseQS', p,delegateFunc);
}

PortfolioWebService.prototype.LoadGeoareaByUniverseQS=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);    
    this.Invoke('LoadGeoareaByUniverseQS', p,delegateFunc);
}



PortfolioWebService.prototype.LoadVCTQSObjects=function(delegateFunc,universe, filter)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);
    p.Add('returnValue',filter);
    this.Invoke('LoadVCTQSObjects', p,delegateFunc);
}

PortfolioWebService.prototype.LoadSPSFManagers=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);
    this.Invoke('LoadSPSFManagers', p,delegateFunc);
}

PortfolioWebService.prototype.LoadManagersByUniverseSF=function(delegateFunc,universe)
{
    var p = new WSParameters();
    p.Add('universeCode',universe);
    p.Add('includeAll',true);
    this.Invoke('LoadManagersByUniverseQS', p,delegateFunc);
}

ChartingWebService.prototype.LoadPerformance = function(delegateFunc, typeCodes, periodType, priceType, methodType, sort, filter)
{
	var p = new WSParameters();

	if (periodType == null) periodType = '';
	if (priceType == null) priceType = 'TR';
	if (methodType == null) methodType = 1;

	p.Add('TypeCodes', typeCodes);
	p.Add('PeriodType', periodType);
	p.Add('PriceType', priceType);
	p.Add('MethodType', methodType);
	
	this.AddStdParams(p, sort, filter);
	this.Invoke('Performance', p, delegateFunc);
}

PortfolioWebService.prototype.AddPortfolioFund= function(delegateFunc,portfolioId, userId, univCode, typeCode)
{
	var p = new WSParameters();

	p.Add('portfolioId', portfolioId);
	p.Add('userId', userId);
	p.Add('univCode', univCode);
	p.Add('typeCode', typeCode);
	this.Invoke('AddPortfolio', p,delegateFunc);
}

PortfolioWebService.prototype.UpdatePortfolioFund= function(delegateFunc,typecode,pDate,quantity,fundcurrency,currency,costV,pCost,rowGuid,port,userId)
{
	var p = new WSParameters();

	p.Add('typecode', typecode);
	p.Add('purchaseDate', pDate);
	p.Add('Quantity', quantity);
	p.Add('fundCurrency', fundcurrency);	
	p.Add('Currency', currency);
	p.Add('isCost', costV);
	p.Add('pCost', pCost);
	p.Add('rowGuid', rowGuid);
	p.Add('pid', port);
	p.Add('userid', userId);
	this.Invoke('UpdatePortfolioFund', p,delegateFunc);
}

PortfolioWebService.prototype.UpdateCash= function(delegateFunc,typecode,quantity,fundcurrency,currency,AccType,name,port,userId)
{
	var p = new WSParameters();
	p.Add('cid', typecode);	
	p.Add('Quantity', quantity);
	p.Add('fundCurrency', fundcurrency);
	p.Add('Currency', currency);
	p.Add('accType', AccType);
	p.Add('accName', name);	
	p.Add('pid', port);
	p.Add('userid', userId);
	this.Invoke('UpdateCash', p,delegateFunc);
}

PortfolioWebService.prototype.CheckUserLogIn=function (delegateFunc,emailId,password)
{
    var p = new WSParameters();
    p.Add('emailId',emailId);
    p.Add('password',password);
    this.Invoke('CheckUserLogIn',p,delegateFunc);
//    var pws = new PortfolioWebService();
//    pws.CheckUserLogIn(emailId,password);
} 

PortfolioWebService.prototype.CalDayLightTime= function(delegateFunc)
{
	var p = new WSParameters();

    this.Invoke('CalCulateDayLightTime',p,delegateFunc);
}
PortfolioWebService.prototype.LoadFilterBusObjects= function(delegateFunc,busCollObjName,univCode,loadMethod,param,nameProperty,codeProperty,filter,sort)
{
	var p = new WSParameters();

    if (param == null) param = '';
    if (filter == null) filter = '';
    
	p.Add('busCollObjName', busCollObjName);
	p.Add('univCode', univCode);
	p.Add('loadMethod', loadMethod);
	p.Add('parameter', param);
	p.Add('nameProperty', nameProperty);
	p.Add('codeProperty', codeProperty);
	p.Add('filter', filter);
	p.Add('sort', sort);
	this.Invoke('LoadFilterBusObject', p,delegateFunc);
}
PortfolioWebService.prototype.LoadFilterBusObjectByUnivGroup= function(delegateFunc,busCollObjName,univGroupCode,parameterType,parameterValue,filter)
{
	var p = new WSParameters();

	if (filter == null) filter = '';
   if (parameterType == null) parameterType = '';
   if (parameterValue == null) parameterValue = '';
    
	p.Add('busCollObjName', busCollObjName);
	p.Add('univGroupCode', univGroupCode);
	p.Add('parameterType', parameterType);
	p.Add('parameterValue', parameterValue);
	p.Add('filter', filter);
	this.Invoke('LoadFilterBusObjectByUnivGroup', p,delegateFunc);
}

PortfolioWebService.prototype.LoadChartFilterBusObjectByUnivGroup= function(delegateFunc,busCollObjName,univGroupCode,parameterType,parameterValue,filter)
{
	var p = new WSParameters();

	if (filter == null) filter = '';
   if (parameterType == null) parameterType = '';
   if (parameterValue == null) parameterValue = '';
    
	p.Add('busCollObjName', busCollObjName);
	p.Add('univGroupCode', univGroupCode);
	p.Add('parameterType', parameterType);
	p.Add('parameterValue', parameterValue);
	p.Add('filter', filter);
	this.Invoke('LoadChartFilterBusObjectByUnivGroup', p,delegateFunc);
}

PortfolioWebService.prototype.LoadBusObjAdoQS= function(delegateFunc,busCollObjName,univCode,nameProperty,codeProperty,filter,sort)
{
	var p = new WSParameters();

    if (filter == null) filter = '';
    
	p.Add('busCollObjName', busCollObjName);
	p.Add('univCode', univCode);
	p.Add('nameProperty', nameProperty);
	p.Add('codeProperty', codeProperty);
	p.Add('filter', filter);
	p.Add('sort', sort);
	this.Invoke('LoadBusObjAdo', p,delegateFunc);
}
PortfolioWebService.prototype.LoadSectorByAssetClassQs= function(delegateFunc,assetClassCode,univCode,nameProperty,codeProperty,filter,sort)
{
	var p = new WSParameters();

    if (assetClassCode == null) assetClassCode = '';
    if (filter == null) filter = '';
    
	p.Add('assetClassCode', assetClassCode);
	p.Add('univCode', univCode);
	p.Add('nameProperty', nameProperty);
	p.Add('codeProperty', codeProperty);
	p.Add('filter', filter);
	p.Add('sort', sort);
	this.Invoke('LoadSectorByAssetClass', p,delegateFunc);
}

PortfolioWebService.prototype.RemovePortfolioFund= function(delegateFunc,portfolioId, userId,  typeCode)
{
	var p = new WSParameters();

	p.Add('portfolioId', portfolioId);
	p.Add('userId', userId);	
	p.Add('typeCode', typeCode);

	this.Invoke('RemovePortfolio', p,delegateFunc);
}

PortfolioWebService.prototype.AddWatchlistFund= function(delegateFunc,userId,univCode,typeCode)
{
	var p = new WSParameters();
	p.Add('userId', userId);	
	p.Add('univCode', univCode);
	p.Add('typeCode', typeCode);   
	p.Add('SiteCode', SiteCode);
	this.Invoke('AddWatchlist', p,delegateFunc);
}

PortfolioWebService.prototype.RemoveWatchlistFund= function(delegateFunc,userId,  typeCode,SiteCode)
{
	var p = new WSParameters();
	
	p.Add('userId', userId);	
	p.Add('typeCode', typeCode);
    p.Add('SiteCode', SiteCode);

	this.Invoke('RemoveWatchlist', p,delegateFunc);
}

PortfolioWebService.prototype.LoadManagerPersons= function(delegateFunc,univCode,loadBy,parameter,nameProperty,codeProperty,filter,sort)
{
	var p = new WSParameters();
	if (parameter == null) return;
	if (filter == null) filter = '';
    
	p.Add('univCode', univCode);
	p.Add('loadMethod', loadBy);
	p.Add('parameter', parameter);
	p.Add('nameProperty', nameProperty);
	p.Add('codeProperty', codeProperty);
	p.Add('filter', filter);
	p.Add('sort', sort);
	this.Invoke('LoadManagerPersons', p,delegateFunc);
}

PortfolioWebService.prototype.LoadFundByType=function(delegateFunc,typeCode)
{
    var p = new WSParameters();
    p.Add('typeCode',typeCode);
    this.Invoke('LoadFundByTypeCode', p,delegateFunc);
}
PortfolioWebService.prototype.LoadPortfolioByUserId=function(delegateFunc,userId)
{
    var p = new WSParameters();
    p.Add('userId',userId);
    this.Invoke('LoadPortfolioByUserId', p,delegateFunc);
}

PortfolioWebService.prototype.LoadWatchlistByUserId=function(delegateFunc,userId)
{
    var p = new WSParameters();
    p.Add('userId',userId);
    this.Invoke('LoadWatchlistByUserId', p,delegateFunc);
}

PortfolioWebService.prototype.IsTypeCodeExistInPortfolio=function(delegateFunc,portfolioId,typeCode)
{
    var p = new WSParameters();
    p.Add('portfolioId',portfolioId);
    p.Add('typeCode',typeCode);
    this.Invoke('IsTypeCodeExistInPortfolio', p,delegateFunc);
}

PortfolioWebService.prototype.LoadFundByTypes=function(delegateFunc,typeCode)
{
    var p = new WSParameters();
    p.Add('typeCode',typeCode);
    this.Invoke('LoadFundByTypeCodes', p,delegateFunc);
}

PortfolioWebService.prototype.UpdateUserCookieDB=function(delegateFunc,userId,cookieName,cookieValue)
{
    var p = new WSParameters();
    p.Add('userId',userId);
    p.Add('cookieName',cookieName);
    p.Add('cookieValue',cookieValue);
    this.Invoke('UpdateUserCookie', p,delegateFunc);
}

// Parameters are as follows:
//   calcType .......... one from [MinMax, MinMean]
//   statisticalType ... e.g. Alpha, Beta, etc.
//   period ............ period over which to make calculations, in months.
//   offset ............ how many months ago should the latest data point be?
//   step .............. in months (interval between data points).
//   number ............ number of data points to return.
//
// Example:
//   LoadRollingDiscreteRange(null, 'MinMax', 'FFISS', 'NASX', 'Alpha', 36, 0, 1, 12)
ChartingWebService.prototype.LoadRollingDiscreteRange = function(delegateFunc, calcType, typeCodes, benchmarkCode, statisticalType, period, offset, step, number)
{
	var p = new WSParameters();

	p.Add('CalcType', typeCodes);
	p.Add('TypeCodes', typeCodes);
	p.Add('BenchmarkCode', benchmarkCode);
	p.Add('StatisticalType', statisticalType);
	p.Add('Period', period);
	p.Add('Offset', offset);
	p.Add('Step', step);
	p.Add('Number', number);

	this.Invoke('GetRollingDiscrete', p, delegateFunc);
}


// Parameters are as follows:
//   statisticalType ... e.g. Alpha, Beta, etc.
//   period ............ period over which to make calculations, in months.
//   offset ............ how many months ago should the latest data point be?
//   step .............. in months (interval between data points).
//   number ............ number of data points to return.
//
// Example:
//   LoadRollingDiscrete(null, 'FFISS', 'NASX', 'Alpha', 36, 0, 1, 12)
ChartingWebService.prototype.LoadRollingDiscrete = function(delegateFunc, typeCodes, benchmarkCode, statisticalType, period, offset, step, number)
{
	var p = new WSParameters();

	p.Add('TypeCodes', typeCodes);
	p.Add('BenchmarkCode', benchmarkCode);
	p.Add('StatisticalType', statisticalType);
	p.Add('Period', period);
	p.Add('Offset', offset);
	p.Add('Step', step);
	p.Add('Number', number);

	this.Invoke('GetRollingDiscrete', p, delegateFunc);
}


ChartingWebService.prototype.LoadEquities = function(delegateFunc, sort, filter)
{
	var p = new WSParameters();
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Equities', p, delegateFunc);
}

ChartingWebService.prototype.LoadInstruments = function(delegateFunc, typeCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('TypeCodes', typeCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Instruments', p, delegateFunc);
}

ChartingWebService.prototype.LoadUnitsByManagerCode = function(delegateFunc, categories, managerCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('Categories', categories);
	p.Add('ManagerCodes', managerCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Units_ByManagerCode', p, delegateFunc);
}

ChartingWebService.prototype.LoadUnitsBySectorClassCode = function(delegateFunc, categories, sectorClassCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('Categories', categories);
	p.Add('SectorClassCodes', sectorClassCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Units_BySectorClassCode', p, delegateFunc);
}

ChartingWebService.prototype.LoadUnitsByFundCode = function(delegateFunc, fundCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('FundCodes', fundCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Units_ByFundCode', p, delegateFunc);
}

ChartingWebService.prototype.LoadFundsByManagerCode = function(delegateFunc, categories, managerCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('Categories', categories);
	p.Add('ManagerCodes', managerCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Funds_ByManagerCode', p, delegateFunc);
}

ChartingWebService.prototype.LoadFundsBySectorClassCode = function(delegateFunc, categories, sectorClassCodes, sort, filter)
{
	var p = new WSParameters();
	p.Add('Categories', categories);
	p.Add('SectorClassCodes', sectorClassCodes);
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Funds_BySectorClassCode', p, delegateFunc);
}

ChartingWebService.prototype.LoadManagers = function(delegateFunc, categories, sort, filter)
{
	var p = new WSParameters();
	
	if (filter == null) filter = '';
	if (sort == null) sort = 'Name';

	// Due to case-sensitivity, and the fact that the Managers method has different case 
	// parameters from the standard, it has to be done the long way.
	p.Add('categories', categories);
	p.Add('pageNo', 1);
	p.Add('pageSize', 0);
	p.Add('filter', filter);
	p.Add('sort', sort);

	this.Invoke('Managers', p, delegateFunc);
}

ChartingWebService.prototype.LoadSectors = function(delegateFunc, categories, officialSectors, sort, filter)
{
	var p = new WSParameters();
	var webMethod = officialSectors ? 'OfficialSectors' : 'Sectors';
	if (sort == null) sort = 'Name';
	if (officialSectors != true)
	{
		officialSectors = false;
	}
	p.Add('Categories', categories);
	this.AddStdParams(p, sort, filter);
	this.Invoke(webMethod, p, delegateFunc);
}

ChartingWebService.prototype.LoadIndices = function(delegateFunc, sort, filter)
{
	var p = new WSParameters();
	if (sort == null) sort = 'Name';
	this.AddStdParams(p, sort, filter);
	this.Invoke('Indices', p, delegateFunc);
}

// This method has not been tested.
ChartingWebService.prototype.LoadStochasticFanByAssetCodes = function(delegateFunc, assetCodes, percentiles, timePeriods, allowForInflation)
{
	var p = new WSParameters();
	p.Add('assetCodes', assetCodes);
	p.Add('percentiles', percentiles);
	p.Add('timePeriods', timePeriods);
	p.Add('allowForInflation', allowForInflation);
	this.Invoke('GetStochasticFan_ByAssetCodes', p, delegateFunc);
}

// This method has not been tested.
ChartingWebService.prototype.LoadStochasticFanByTypeCodes = function(delegateFunc, typeCodes, percentiles, timePeriods, allowForInflation)
{
	var p = new WSParameters();
	p.Add('typeCodes', typeCodes);
	p.Add('percentiles', percentiles);
	p.Add('timePeriods', timePeriods);
	p.Add('allowForInflation', allowForInflation);
	this.Invoke('GetStochasticFan_ByTypeCodes', p, delegateFunc);
}

ChartingWebService.prototype.AddStdParams = function(p, sort, filter)
{
	if (filter == null) filter = '';
	if (sort == null) sort = '';
	p.Add('PageNo', 1);
	p.Add('PageSize', 0);
	p.Add('Filter', filter);
	p.Add('Sort', sort);
}

ChartingWebService.prototype.Invoke = function(webMethod, params, delegateFunc)
{
	if (delegateFunc == null) 
	{
		delegateFunc = LoadServiceTest;
		if (webMethod.indexOf('GetRollingDiscrete') == 0)
		{
			delegateFunc = LoadServiceTestString;
		}
	}
	Debug(params.Length == 0, 'Invoke method: params is empty for method "' + webMethod + '"');
	if (DebugAlertOnWebServiceExec)
	{
		var msg = 'Executing ' + webMethod + ' method';
		if (DebugAlertShowParamsOnExec)
		{
			msg += ' with parameters:\n' + params.ToString();
		}
		Debug(true, msg);
	}

	try
	{
		SOAPClient.invoke(this.WebServiceUrl, webMethod, params.ToSoap(), true, delegateFunc);
	}
	catch (ex)
	{
		Debug(true, 'Error invoking web service.\nUrl: ' + this.WebServiceUrl + '\nMethod: ' + webMethod + '\nParameters: ' + params.ToString() + '\nException: ' + ex);
	}
}

PortfolioWebService.prototype.Invoke = function(webMethod, params, delegateFunc)
{

	Debug(params.Length == 0, 'Invoke method: params is empty for method "' + webMethod + '"');
	if (DebugAlertOnWebServiceExec)
	{
		var msg = 'Executing ' + webMethod + ' method';
		if (DebugAlertShowParamsOnExec)
		{
			msg += ' with parameters:\n' + params.ToString();
		}
		Debug(true, msg);
	}

	try
	{
		SOAPClient.invoke(this.WebServiceUrl, webMethod, params.ToSoap(), true, delegateFunc);
	}
	catch (ex)
	{
		Debug(true, 'Error invoking web service.\nUrl: ' + this.WebServiceUrl + '\nMethod: ' + webMethod + '\nParameters: ' + params.ToString() + '\nException: ' + ex);
	}
}

//####################################################################
// Parameters collection
//####################################################################
function WSParameters()
{
	this.names = new Array();
	this.values = new Array();
}

WSParameters.prototype.Add = function(name, value)
{
	this.names[this.names.length] = name;
	this.values[this.values.length] = value;
}

WSParameters.prototype.Length = function()
{
	return this.names.length;
}

WSParameters.prototype.ToString = function(separator)
{
	var res = '', sep = '';
	if (separator == null) separator = '\n';
	for (var i = 0; i < this.names.length; i++)
	{
		res += sep + this.names[i] + '="' + this.values[i] + '"';
		sep = separator;
	}
	return res;
}

WSParameters.prototype.ToSoap = function()
{
	var p = new SOAPClientParameters();
	for (var i = 0; i <this.names.length; i++)
	{
		p.add(this.names[i], this.values[i]);
	}
	return p;
}

//####################################################################
// Helper functions below this point 
//####################################################################

function GetElementById(id, msgOnFail)
{
	if (msgOnFail == null) msgOnFail = true;
	var element = document.getElementById(id);
	Debug(element == null && msgOnFail, "Unable to locate element with id='" + id + "'");
	return element;
}


// This method can be safely run in client scripts. 
// Use instead of alert(message).
function Debug(condition, message)
{
	var href = document.location.href.toLowerCase();
	var urlDebug = href.indexOf('debugalert=1') > -1 || href.indexOf('debugalert=y') > -1;

	if (!(condition && (DebugAlert || urlDebug))) return;

	var div = null;	
	var doAlert = true;

	if (UseDebugPanel)
	{
		try
		{
			div = GetDebugPanel(); // this may fail if the document hasn't loaded fully.
			doAlert = false;
		}
		catch (e) { }
	}
	
	if (!doAlert)
	{
		div.Write(message);
	}
	else
	{
		alert(message);
	}
}

// This function is used to populate drop-down boxes.
// Parameters:
//   xmlResult ....... the parameter result from the web service.
//   selectControl ... either the id of an element in the document or the element itselft. Must be a <SELECT>.
//   itemPlural ...... a string denoting the type of item, e.g. 'funds', 'indices', etc.
function LoadOptionList(xmlResult, selectControl, itemPlural)
{
	var data = null;
	var sc = selectControl;
	
	if (sc != null && sc.options == null)
	{
		sc = GetElementById(sc);
	}

	sc.options.length = 0;

	if (xmlResult == null || xmlResult.Items == null)
	{
		return;
	}
	
	data = xmlResult.Items;
    if(selectControl.indexOf("qs")>=0)
	sc.options.add(new Option("All "+itemPlural,''), 0);
	else
	InfoFirstItem(sc, data.length, itemPlural);
	for (var i = 0; i < data.length; i++)
	{
		sc.options.add(new Option(data[i].Name, data[i].Code), sc.options.length);
	}
}

// This function can be over-ridden with a custom function as required.
function InfoFirstItem(selectControl, itemCount, itemPlural)
{
	var text = null;
	if (itemCount > 1)
	{
		text = itemCount + " " + itemPlural + " found...";
	}
	else if (itemCount < 1)
	{
		text = "0 " + itemPlural + " found!";
	}
	
	if (text != null)
	{
		selectControl.options.add(new Option(text, ""), 0)
	}
}

//####################################################################
// Test functions below this point
//####################################################################

// Used to test web service result set when result is not a string.
// If the delegate provided by a service is set to null, then either this function or the one below
// will be called. Ensure that DebugAlert is set to true to get a result.
function LoadServiceTest(r)
{
	Debug(r == null, 'LoadServiceTest: parameter "r" was unexpectedly null');
	var data = r.Items;
	if (data == null) data = r.PerfItems;
	Debug(data == null, 'LoadServiceTest: parameter "r" does not contain required property. Must contain either "Items" or "PerfItems".');
	Debug(true, 'LoadServiceTest: data.length is ' + data.length);
}

// Used to test web service result set when result is a string.
function LoadServiceTestString(r)
{
	Debug(r == null, 'LoadServiceTest: parameter "r" was unexpectedly null');
	Debug(true, 'LoadServiceTestString:\n' + r);
}

function TestSuite()
{
	var cws = new ChartingWebService();
	
	Debug(true, 'Tests are asynchronous and may not appear in order.');
	
	Debug(true, 'Testing LoadPerformance...');
	cws.LoadPerformance(null, 'FFISS,FTSENVA');
	
	Debug(true, 'Testing LoadInstruments...');
	cws.LoadInstruments(null, 'FFISS,FTSENVA');
	
	Debug(true, 'Testing LoadUnitsBySectorClassCode...');
	cws.LoadUnitsBySectorClassCode(null, 'OIC', 'U:UG');
	
	Debug(true, 'Testing LoadPerformance...');
	cws.LoadUnitsByManagerCode(null, 'OIC', 'FIDE');
	
	Debug(true, 'Testing LoadSectors...');
	cws.LoadSectors(null, 'OIC', false);

	Debug(true, 'Testing LoadSectors...');
	cws.LoadSectors(null, 'OIC', true);
	
	Debug(true, 'Testing LoadRollingDiscrete...');
	cws.LoadRollingDiscrete(null, 'FFISS', 'NASX', 'Alpha', 36, 0, 1, 12);
	
	Debug(true, 'Testing LoadRollingDiscreteRange...');
	cws.LoadRollingDiscreteRange(null, 'MinMax', 'FFISS', 'NASX', 'Alpha', 36, 0, 1, 12)
	
	Debug(true, 'Testing LoadEquities...');
	cws.LoadEquities(null, "Code LIKE 'EE%' OR Code LIKE 'F%'");
	
	Debug(true, 'Testing LoadIndices...');
	cws.LoadIndices(null, "Source='FTET' OR Source='FTVU' OR Source='MISC'");
}

//####################################################################
// Functions and methods below should not be called directly by client scripts.
// They are called via the Debug function as required.
//####################################################################

function GetDebugPanel()
{
	var div = document.getElementById('DebugPanel');
	if (div == null) 
	{
		div = new DebugPanel();
	}
	else
	{
		div = div.PanelRef;
	}
	return div;
}


function DebugPanel()
{
	var body = document.getElementsByTagName('BODY')[0];
	var div = document.createElement('DIV');
	var hdgStyle = ''
	
	div.id = 'DebugPanel';
	div.className = 'DebugPanel';
	if (!DebugPanelUseCustomStyle)
	{
		div.style.position = 'absolute';
		div.style.width = '350px';
		div.style.left = (document.body.clientWidth - 370) + 'px';
		div.style.top = '20px';
		div.style.fontFamily = 'Arial, Verdana, Sans-Serif';
		div.style.fontSize = '12px';
		div.style.display = 'block';
		div.style.border = 'solid 1px black';
		div.style.backgroundColor = '#E0E0FF';
		div.style.padding = '2px';
		hdgStyle = ' style="font-weight:bold; border-bottom: solid 1px black;"'
	}
	div.innerHTML = '<div class="DebugHeading"' + hdgStyle + '>Debug Window</div>';
	
	body.insertBefore(div, null);	
	
	this.Div = div;
	div.PanelRef = this;
}


DebugPanel.prototype.Write = function(message)
{
	var div = document.createElement('DIV');
	this.Div.insertBefore(div, null);
	div.className = 'DebugEntry';
	if (!DebugPanelUseCustomStyle)
	{
		div.style.borderBottom = 'solid 1px black';
	}
	div.innerText = message;
}

//####################################################################