/*
 *+------------------------------------------------------------------------+
 *| Licensed Materials - Property of IBM
 *| BI and PM: prmt
 *| (C) Copyright IBM Corp. 2002, 2018
 *|
 *| US Government Users Restricted Rights - Use, duplication or
 *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
 *|
 *+------------------------------------------------------------------------+
*/


/**
	@private
	@class
*/
cognos.Prompt.Control.Tree = cognos.Prompt.Control.f_extend({

	f_initialize: function( v_oProps ) {
		this._type_ = "cognos.Prompt.Control.Tree";
		this.f_parent( v_oProps ); // call parent's initialize()

		this.f_initCompleted();
	},

	checkData: function() {
		var v_oTree = this.f_getTree();
		if ( !v_oTree ) {
			this.m_bValid = ( this["@required"] ? false : true );
		} else {

			this.f_getPV();
	
			if (( (!this.isRequired() || v_oTree.getRootNode().hasSelectedChildren() ) && v_oTree.checkDefaultValid() ) || v_oTree.getPreviousSelections() !== null ) {
				this.m_bValid = true;
			}
			else {
				this.m_bValid = false;
			}
		}
		this.f_parent(); // call parent's checkData

		return this.m_bValid;
	},

	clearValues: function() {
		this.f_parent();
		this.f_getTree().deSelectAll();
	},

	f_drawCompleted: function()
	{
		var v_oTree = null;
		this.m_elPrompt = $( this.f_getId("treePane") );
		if (this.isRequired()) {
			this.setAriaRequired();
		}
		
		var b_iOS = ( navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false ); 
		if(!b_iOS){
			v_oTree = window[ this.f_getId("CTree_") ] = new CInnerTree (
			$( this.f_getId("PRMT_TREE_CONTAINER_") ),
			$( this.f_getId("_TreeSubmit") ) ,
			this.isRequired(),
			this.isMulti(),
			this.f_getId("CTree_"),
			null,
			null,
			this.f_getCVId(),
			this["@style"],
			this["@contentTextDirection"],
			this.getName(),
			this);		
		} else 
		{
		 	v_oTree = window[ this.f_getId("CTree_") ] = new CInnerTreeIOS (
			$( this.f_getId("PRMT_TREE_CONTAINER_") ),
			$( this.f_getId("_TreeSubmit") ) ,
			this.isRequired(),
			this.isMulti(),
			this.f_getId("CTree_"),
			null,
			null,
			this.f_getCVId(),
			this["@style"],
			this["@contentTextDirection"],
			this.getName(),
			this);
		}
		
		var v_aRO = this.f_getCV().repromptObserverArray;
		if (v_aRO) {
			v_aRO.push( v_oTree );
		}
		
		var v_oRootNode = v_oTree.getRootNode();
		v_oTree.setWrapper( this );
		v_oTree.setMustChangeDefaultValue( this["@mustChangeDefault"] );
		v_oTree.setHideAdornments( this["@hideAdornments"] );
		v_oTree.setHideOuterTable( true );
		v_oTree.setPromptingTree( this["@parameter"] );
		if ( this["@rowsPerPage"] )
		{
			v_oTree.setMaxValueCount( parseInt(this["@rowsPerPage"], 10) );
		}
		if ( this["@showPreviousValues"] )
		{
			v_oTree.setShowPreviousValues( this["@showPreviousValues"] );
		}
		var v_sWidth = cssParser( this["@style"], "width", true );
		if ( v_sWidth )
		{
			v_oTree.setContainerWidth( v_sWidth );
		}

		var v_sHeight = cssParser( this["@style"], "height", true );
		if ( v_sHeight )
		{
			v_oTree.setContainerHeight( v_sHeight );
		}


		if ( this[K_PRMT_sATTR_DISABLED] )
		{
			v_oTree.setDisabled( true );
		}

		if (typeof tntGeneric == K_PRMT_sUNDEFINED)
		{
			tntGeneric = new CTreeNodeType(TREE_FOLDER, true, this.m_sSkin + "/prompting/images/genericTreeNode.gif", this.m_sSkin + "/prompting/images/genericTreeNode.gif");
		}

		var v_oSO = null;
		var v_oSC = this.getSelectChoices();
		if ( v_oSC && v_oSC.c && v_oSC.c.length > 0)
		{
			for ( var v_idx = 0; v_idx < v_oSC.c.length; v_idx++ )
			{
				v_oSO = v_oSC.c[v_idx];
				v_oTree.addToPrevSelArray( v_oSO[K_PRMT_sATTR_USE_VALUE], v_oSO[K_PRMT_sATTR_DISPLAY_VALUE] );
			}
		}

		var v_oSA = {};
		var v_nSA = this.f_getChildByTagName( "selectChoicesAncestry" );
		if ( v_nSA && v_nSA.c && v_nSA.c.length)
		{
			for ( var v_idxSA = 0; v_idxSA < v_nSA.c.length; v_idxSA++ )
			{
				v_oSA[ sDecodeU003( v_nSA.c[v_idxSA][K_PRMT_sATTR_USE_VALUE] ) ] = true;
			}
		}
		v_oTree.m_oAncestry = v_oSA;

		var v_aSO = this.getSelectOptions();
		if (v_aSO )
		{
			for ( var v_idx = 0; v_idx < v_aSO.length; v_idx++ )
			{
				v_oSO = v_aSO[v_idx];
				if ( v_oSO.n == "selectTreeOption" )
				{
					this.f_addNode( v_oRootNode, v_oSO );
				}
			}
		}

		v_oSO = this.getChildByName("selectOptions");
		if (v_oSO)
		{
			var v_iSkip = parseInt( v_oSO["@skipValueCount"], 10 );
			if ( !isNaN(v_iSkip) && v_iSkip >= 0 )
			{
				v_oRootNode.setSkipValueCount( v_iSkip );
			}
			var v_iMVC= parseInt( v_oSO["@maximumValueCount"], 10 );
			if ( !isNaN(v_iMVC) && v_iMVC >= 0 )
			{
				v_oTree.setMaxValueCount( v_iMVC );
			}

			if ( v_oSO["@moreData"] )
			{
				v_oRootNode.setMoreData(true);
				var theNodeRef = v_oTree.getName() + v_oRootNode.getTreeRef();
				setTimeout( v_oTree.drawMoreData.bind(v_oTree, v_oRootNode, theNodeRef), 250 );
			}
		} else {
			this["@canExpand"] = false;
		}
		
		v_oTree.setNodesCanHaveChildren( this["@canExpand"] !== false );

		if ( !this["@multiSelect"] )
		{
			v_oTree.setRecursiveSelect(false);
		}

		v_oTree.drawAll();
		v_oTree.updateSelections(v_oTree.getRootNode());

		PRMTUtils.f_addEvent( $( this.f_getId("C_TREE_aSelAll") ), "click", v_oTree.selectAll.bind(v_oTree) );
		PRMTUtils.f_addEvent( $( this.f_getId("C_TREE_aSelNone") ), "click", v_oTree.deSelectAll.bind(v_oTree) );

		if (v_oTree.getSelectionMode() != SINGLE_TREE_SELECTION && (v_oTree.getSelectTreeUI() != CHECKBOX_TREE || v_oTree.getSelectionMode() != DISCONTIGUOUS_TREE_SELECTION) )
		{
			var v_a = $( this.f_getId("C_TREE_aSelAll") );
			if ( v_a )
			{
				v_a.style.display = K_PRMT_sEMPTY;
			}
		}

		// link a11y label if it exists
		var v_a11yLabel = $( this.f_getId("PRMT_LBL_") );
		if ( v_a11yLabel ) {
			var v_container = $( this.f_getId("CTree_") );
			v_container.setAttribute("aria-labelledby", this.f_getId("PRMT_LBL_"));
		}

		this.m_oTree = v_oTree;
		this.f_parent(); // call parent's f_drawCompleted
	}
});

/**
	See {@link cognos.Prompt.Control.addValues} for more info.
	@param {cognos.Value[]}
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.addValues = function( v_aValues )
{
	var v_oValue;
	var v_oTree = this.f_getTree();
	if ( this.isMulti() )
	{
		for (var v_idx = 0; v_idx < v_aValues.length; v_idx++)
		{
			v_oValue = v_aValues[v_idx];
			v_oTree.addToPrevSelArray( v_oValue[K_PRMT_sUSE], v_oValue[K_PRMT_sDISPLAY] )
		}
	}
	else
	{
		this.clearValues();
		if ( v_aValues.length )
		{
			v_oTree.addToPrevSelArray( v_aValues[0][K_PRMT_sUSE], v_aValues[0][K_PRMT_sDISPLAY] )
		}
	}
};

/**
	@private
	@param {CInnerTreeNode} v_nParent
	@param {HTMLelement} v_oSO
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.f_addNode = function( v_nParent, v_oSO )
{
	if ( v_oSO )
	{
		var v_node = new CInnerTreeNode(v_nParent, tntGeneric, false, v_oSO[K_PRMT_sATTR_DISPLAY_VALUE], v_oSO[K_PRMT_sATTR_USE_VALUE], false);
		if ( v_oSO.c && v_oSO.c.length )
		{
			for (var v_idx = 0; v_idx < v_oSO.c.length; v_idx++)
			{
				this.f_addNode( v_node, v_oSO.c[v_idx] );
			}
		}
	}
};

/**
	Sets the JavaScript references used by custom scripts based on generated code from Blaring and before.
	(Custom Scripts Workaround)
	@private
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.f_CSW_init = function()
{
	this.f_CSW_createJSObject( "tree", this.f_getTree() );
};

/**
	@private
	@param {C_PromptElement} v_el Container.
	@return {C_PromptElement}
*/
cognos.Prompt.Control.Tree.prototype.f_drawInput = function( v_el )
{
	$CE("input", {"type": "hidden", "id": this.f_getId("_TreeSubmit"), "value": this["@defaultDate"]}, v_el );
	var v_sClassName = (PRMTUtils.f_isHighContrast()? "clsPromptComponent clsPrompt_a11y":"clsPromptComponent");
	var v_oContainer = $CE("div", {"id": this.f_getId("PRMT_TREE_CONTAINER_"), "class":v_sClassName}, v_el);
	v_oContainer.f_appendText(K_PRMT_sEMPTY);
	return v_oContainer;
};

/**
	Renders the layout of the control: position lists, adornments and control inputs.
	@private
	@param {C_PromptElement} v_trLayout Container for this control.
	@return {C_PromptElement}
*/
cognos.Prompt.Control.Tree.prototype.f_drawLayout = function( v_trLayout )
{
	var v_container = null;
	var v_sWidth = cssParser(this["@style"], "width", true);
	// set to 100% only if already set to relative size
	v_sWidth = ( (/\d%/).test( v_sWidth ) ? "100%" : K_PRMT_sEMPTY );

	var v_sWidthInStyle = cssParser( this["@style"], "width" );

	if ( this.isMulti() )
	{
		var v_td1 = $CE( "td", {"width":v_sWidth}, v_trLayout );

		var v_tbl = $CE( "table", {"border": K_PRMT_DEBUG_TABLEBORDER, "cellPadding":0, "cellSpacing":0, "role":K_PRMT_ARIA_ROLE_PRESENTATION}, v_td1 );
		var v_tbd = $CE( "tbody", {}, v_tbl );
		var v_tr = $CE( "tr", {}, v_tbd );
		if ( !(this["@hideAdornments"] || this.m_bSkipAdornments) )
		{
			this.f_drawAdornments( v_tr );
		}
		var v_td = $CE( "td", {}, v_tr );

		if ( v_sWidthInStyle )
		{
			v_td1.f_setProperty( "width", "100%" );
			v_tbl.f_setProperty( "width", "100%" );
			v_td.f_setProperty( "width", "100%" );
		}
		v_container = v_td;
		v_tr = $CE( "tr", {}, v_tbd );
		var v_sCustomDir = cssParser( this["@style"], "direction", true );
		var v_FinalDir = ((v_sCustomDir == "ltr" || v_sCustomDir == "rtl") ? v_sCustomDir : PRMT_BidiUtils.lookupDirection($( this.f_getId(this.m_sDivPrefix) )));
		var v_sAlignStyle = ( ( v_FinalDir  == "rtl" ) ? "left" : "right");
		v_td = $CE( "td", {"colSpan": "2", "align": v_sAlignStyle}, v_tr );

		if ( this[K_PRMT_sATTR_DISABLED] )
		{
			this.drawDisableSelectLink(v_td, v_sAlignStyle);
		}
		else
		{
			this.drawSelectLink(v_td, v_sAlignStyle);
		}
	}
	else
	{
		if ( !(this["@hideAdornments"] || this.m_bSkipAdornments) )
		{
			this.f_drawAdornments( v_trLayout );
		}
		v_container = $CE( "td", {}, v_trLayout );
	}

	if ( !this["@hideOuterTable"] )
	{
		v_container = $CE( "div", {"id": this.f_getId("treePane"), "class": "clsTreePane pa"}, v_container );
	}

	var v_sStyle = "";
	if ( v_sWidthInStyle )
	{
		v_sStyle += v_sWidthInStyle;
	}
	var v_sHeightInStyle = cssParser( this["@style"], "height" );
	if ( v_sHeightInStyle )
	{
		v_sStyle += v_sHeightInStyle;
	}
	if ( v_sStyle )
	{
		// Setting padding to 0px because IE and Firefox doesn't have the same box model.
		// Width/Height in IE include the padding, not in Firefox (Firefox does it the right way).
		// Setting vertical-align to top, for cases where the container is a TD.
		v_container.f_setProperty( "style", "vertical-align:top;overflow:auto;padding:0px;" + v_sStyle );
	}

	return (this.m_elPrompt = this.f_drawInput( v_container ));
};

/**
	@private
	@return {cognos.Value[]}
*/
cognos.Prompt.Control.Tree.prototype.f_getPV = function()
{
	var v_oTree = this.f_getTree();

	var children = v_oTree.getRootNode().getChildren();
	if (children.length > 0)
	{
		for (var j = 0; j < children.length; j++)
		{
			v_oTree.processTree(children[j]);
		}
	}

	var v_aPV = [];

	this.f_getPVforNodes( v_aPV, v_oTree.getRootNode(), v_oTree.nodesCanHaveChildren() );

	var v_aPrevSel = v_oTree.getPreviousSelections();
	if (v_aPrevSel != null)
	{
		// Create a dictionary based on the use value to find duplicates.
		var v_dicUseValues = {};
		for (var v_idxPV = 0; v_idxPV < v_aPV.length; v_idxPV++)
		{
			v_dicUseValues[ v_aPV[v_idxPV][K_PRMT_sUSE] ] = v_aPV[v_idxPV][K_PRMT_sDISPLAY];
		}
		for (var i = 0; i < v_aPrevSel.length; i++)
		{
			var v_sUse = null;
			var v_sDisplay = null;
			if (typeof v_aPrevSel[i] == K_PRMT_sSTRING) //deprecated
			{
				v_sUse = v_aPrevSel[i];
				v_sDisplay = v_aPrevSel[i];
			}
			else if (typeof v_aPrevSel[i] == K_PRMT_sOBJECT)
			{
				v_sUse = v_aPrevSel[i][1];
				v_sDisplay = v_aPrevSel[i][0];
			}

			// add only if it's not already in the parameter values.
			if ( v_sUse !== null && ( v_sDisplay === null || typeof v_sDisplay == K_PRMT_sUNDEFINED || !v_dicUseValues[v_sUse] ) )
			{
				var v_oPV = {"use": v_sUse};
				if ( v_sDisplay !== null && typeof v_sDisplay != K_PRMT_sUNDEFINED )
				{
					v_oPV[K_PRMT_sDISPLAY] = v_sDisplay;
				}
				v_aPV.push( v_oPV );
			}
		}
	}

	if ( v_aPV.length == 0 )
	{
		v_aPV = null;
	}
	else if ( v_aPV.length == 1 )
	{
		v_aPV = v_aPV[0];
		if ( typeof v_aPV[K_PRMT_sUSE] == K_PRMT_sUNDEFINED || v_aPV[K_PRMT_sUSE] === null )
		{
			v_aPV = null;
		}
	}
	return v_aPV;
};

/**
	@private
	@param {cognos.Value[]} v_aPV array to use to store values, passed by reference.
	@param {HTMLElement} v_nNode
	@param {boolean} v_bCanHaveChildren
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.f_getPVforNodes = function( v_aPV, v_nNode, v_bCanHaveChildren )
{
	if (v_nNode.isSelected())
	{
		v_aPV.push( {"use": v_nNode.getValue(), "display": v_nNode.getName()} );
		this.f_getTree().removeFromPrevSelArray( v_nNode.getValue() );
	}
	if ( (v_bCanHaveChildren || v_nNode == v_nNode.m_oRoot) && v_nNode.hasSelectedChildren() )
	{
		var children = v_nNode.getChildren();
		if ( children.length > 0 )
		{
			for (var j = 0; j < children.length; j++)
			{
				this.f_getPVforNodes( v_aPV, children[j], v_bCanHaveChildren );
			}
		}
	}
};

/**
	@private
	@return {CInnerTree}
*/
cognos.Prompt.Control.Tree.prototype.f_getTree = function()
{
	return (this.m_oTree);
};

/**
	@private
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.f_setSelectChoices = function() {
};


/**
 *  Small wrapper around f_getPV, returns "false" if f_getPV result array is empty.
 *
	@private
	@return {Boolean}
*/
cognos.Prompt.Control.Tree.prototype.hasInputValue = function()
{
	var v_aTmp = this.f_getPV();
	return (v_aTmp && v_aTmp != null && v_aTmp.length && v_aTmp.length > 0 ? true : false);
};

/**
 *  Builds the Select All links 
 *
	@private	
	@param {HTMLElement} v_td : the TD element under which we should create the disabled links (Select All and Deselect All)
	@param {string} v_sAlignStyle : indicates if the GUI is mirrored 
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.drawDisableSelectLink = function(v_td, v_sAlignStyle)
{
	if (v_sAlignStyle == "right")
	{
		var v_span = $CE( "span", {"id": this.f_getId("C_TREE_aSelAll"), "class": "clsLink pl", "style": "margin-right:5px;display:none;text-decoration:underline;color: #CCCCCC" }, v_td );
		v_span.f_appendText( this[K_PRMT_LABEL_RESULTS_SELECT_ALL] );

		v_span = $CE( "span", { "id": this.f_getId("C_TREE_aSelNone"), "class": "clsLink pl", "style": "text-decoration:underline;color: #CCCCCC" }, v_td );
		v_span.f_appendText(this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] );
	}
	else
	{
		var v_span = $CE( "span", { "id": this.f_getId("C_TREE_aSelNone"), "class": "clsLink pl", "style": "text-decoration:underline;color: #CCCCCC" }, v_td );
		v_span.f_appendText(this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] );
				
		v_span = $CE( "span", {"id": this.f_getId("C_TREE_aSelAll"), "class": "clsLink pl", "style": "margin-left:5px;display:none;text-decoration:underline;color: #CCCCCC" }, v_td );
		v_span.f_appendText( this[K_PRMT_LABEL_RESULTS_SELECT_ALL] );
	}
};

/**
 *  Builds the Select All links 
 *
	@private	
	@param {HTMLElement} v_td : the TD element under which we should create the enabled links (Select All and Deselect All)
	@param {string} v_sAlignStyle : indicates if the GUI is mirrored 
	@return {void}
*/
cognos.Prompt.Control.Tree.prototype.drawSelectLink = function(v_td, v_sAlignStyle)
{
	if (v_sAlignStyle == "right")
	{	
		var v_a = $CE( "a", {"id": this.f_getId("C_TREE_aSelAll"), "class": "clsLink pl", "href": "javascript:;", "onclick": "document.location.hash='';", "style": "margin-right:5px;display:none;"}, v_td );
		v_a.f_appendText(PMT_UIM_SELECTALL);
		v_a = $CE( "a", {"id": this.f_getId("C_TREE_aSelNone"), "class": "clsLink pl", "href": "javascript:;", "onclick": "document.location.hash='';"}, v_td );
		v_a.f_appendText( this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] );
	}
	else
	{
		v_a = $CE( "a", {"id": this.f_getId("C_TREE_aSelNone"), "class": "clsLink pl", "href": "javascript:;", "onclick": "document.location.hash='';"}, v_td );
		v_a.f_appendText( this[K_PRMT_LABEL_RESULTS_DESELECT_ALL] );
		var v_a = $CE( "a", {"id": this.f_getId("C_TREE_aSelAll"), "class": "clsLink pl", "href": "javascript:;", "onclick": "document.location.hash='';", "style": "margin-left:5px;display:none;"}, v_td );
		v_a.f_appendText(PMT_UIM_SELECTALL);	
	}
};