function enlistYtVideosOptionsMold()
{
    this.videoListContainerId = null;
    this.videoUnitContainerStyleClass = null;
    this.playerWidth = 425;
    this.playerHeight = 356;
    this.videoNumPerPage = 10;
    this.showNaviArrow = true;
    this.naviArrowStyleClass = null;
    this.displayElementOrder = "t,p,d";     // t: title, p: thumbnail, d: description
    this.thumbnailType = -1;     // -1 to 3.
                                // When it's -1, randomly select thumbnail type from 0 to 2
                                // 3 is high resolution thumbnail, means bigger size
    this.thumbnailStyleClass = null;
    this.titleLength = 15;  // The number of characters. Extra 3 characters will be added at
                            // the end (so actual total length will be titleLength + 3) when
                            // title is longer than this number
    this.titleStyleClass = null;
    this.titleInTooltip = true;
    this.descriptionLength = 20;
    this.descriptionStyleClass = null;
    this.descriptionInTooltip = true;
    this.swfobjParams = null;
    this.swfobjAttribs = null;
    this.ytPlayerPlaceHolderId = null;
}

/**
 * Trim beginning and last spaces
 * Input:
 *  originStrData: String data
 * Output:
 *  Normal: String trimmed beginning and last spaces
 *  Error: null (including the case that input data is empty string)
 */
function ytTrimEdgeSpaceChar( originStrData) {
    if ( ( typeof originStrData).toLowerCase() != "string") return null;
    var strData = originStrData.replace( new RegExp( "^ +"), "");
    strData = strData.replace( new RegExp( " +$"), "");
    if ( strData.length < 1) return null;
    return strData;
}
function ytNumIntegrityCheck( numData) {
    if ( ( typeof numData).toLowerCase() != "number") return false;
    return true;
}
function ytBooleanIntegrityCheck( booleanData) {
    if ( ( typeof booleanData).toLowerCase() != "boolean") return false;
    return true;
}

function method_closure( obj, methodObj, opt_argArray)
{
	return function() {
		return methodObj.apply( obj, opt_argArray);
	};
} // function method_closure( obj, methodObj, opt_argArray)

function ytPlayerNodeUpdateDetector( ytPlayerPlaceHolderIdInput, ytPlayerNodeIdInput) {
    this.ytPlayerPlaceHolderId = ytPlayerPlaceHolderIdInput;
    this.ytPlayerNodeId = ytPlayerNodeIdInput;
    this.showCloseButton = false;
    this.intervalId = null;
    this.holderNodeRemovedFlag = false;
    this.changeMonitor = { name:"changeMonitor", value:"BeforeChange"};

    this.setChangeMonitorAttribute =
        function() {
            var preChangeYtPlayerNode = document.getElementById( this.ytPlayerPlaceHolderId);
            preChangeYtPlayerNode.setAttribute( this.changeMonitor.name, this.changeMonitor.value);
        };

    this.verifyNode =
        function( renewedYtPlayerNodeId) {
            var returnCode = false;
            var ytPlayerNodeAfterInterval = ytPlayerNodeAfterInterval = document.getElementById( renewedYtPlayerNodeId);
            if ( ytPlayerNodeAfterInterval) {
                var changeMonitorAttribValue = ytPlayerNodeAfterInterval.getAttribute( this.changeMonitor.name);
                if ( changeMonitorAttribValue != this.changeMonitor.value) {
                    clearInterval( this.intervalId);
                    removeYtPlayerFromHolder( swfobjAttribsObj.id);
                    addYtPlayerIdIntoHolder( renewedYtPlayerNodeId);
                    returnCode = true;
                }
            }
            return returnCode;
        };
    this.checkUpdate =
        function() {
            if ( !this.holderNodeRemovedFlag) {
                if ( !this.verifyNode( this.ytPlayerPlaceHolderId)){
                    if ( document.getElementById( this.ytPlayerPlaceHolderId) == null) {
                        this.holderNodeRemovedFlag = true;
                        this.verifyNode( this.ytPlayerNodeId);
                    }
                }
            }
            else {
                this.verifyNode( this.ytPlayerNodeId);
            }
        };
}

var ytPlayerHandler = {
    /**
     * This will be called from onclick event on a video summary unit of video list
     * Use google event api to add this event to onclick action. Because, setAttribute seems to be not able to work on IE.
     * Before calling to this function, everything should be defined previously
     */
    renewYtPlayer : function ( ytSwfUrl, behaviorDirector, ytPlayerPlaceHolderId, playerWidth, playerHeight, swfobjParamsObj, swfobjAttribsObj) {
        var ytPlayerHolderNodeId = ytPlayerPlaceHolderId;
        switch( behaviorDirector) {
            case 0:
            case 2:
            case 4:
                ytPlayerHolderNodeId = swfobjAttribsObj.id;
                break;
        } // switch

        // Since control logic flow comes here always when user clicks on one of listed video info,
        // YouTube video player being generated should be displayed.
        if ( (typeof swfobjAttribsObj).toLowerCase() != "undefined") {
            if ( swfobjAttribsObj != null) {
                for( var swfobjAttribIndex in swfobjAttribsObj) {
                    if ( swfobjAttribIndex.toLowerCase() == "style") {
                        if ( swfobjAttribsObj[ swfobjAttribIndex] != null) {
                            swfobjAttribsObj[ swfobjAttribIndex] =
                                swfobjAttribsObj[ swfobjAttribIndex].replace( new RegExp( "\\bdisplay\\s*:\\s*none\\s*;*", "gi"), "display:block;");
                        }
                        else {
                            swfobjAttribsObj[ swfobjAttribIndex] = "display:block;";
                        }
                    }
                } // for
            }
        }


        var ytPlayerNodeUpdateDetectorObj = new ytPlayerNodeUpdateDetector( ytPlayerHolderNodeId, swfobjAttribsObj.id);
        ytPlayerNodeUpdateDetectorObj.setChangeMonitorAttribute();
        ytPlayerNodeUpdateDetectorObj.intervalId = 
            setInterval( method_closure( ytPlayerNodeUpdateDetectorObj, ytPlayerNodeUpdateDetectorObj.checkUpdate, []), 250);
        swfobject.embedSWF(
            ytSwfUrl, ytPlayerHolderNodeId, playerWidth.toString(), playerHeight.toString(),
            '8', null, null, swfobjParamsObj, swfobjAttribsObj
            );
    }
};

function ytTitleDescriptionCommonTask( styleClass, videoInfoStr, videoInfoStrLength, videoUnitContainer) {
    var ytVideoInfoDivNode = document.createElement( "div");
    if ( styleClass != null) {
        ytVideoInfoDivNode.className = styleClass;
    }
    var trancatedVideoInfoStr = videoInfoStr;
    if ( videoInfoStr.length > videoInfoStrLength) trancatedVideoInfoStr = videoInfoStr.substr( 0, videoInfoStrLength) + "...";
    ytVideoInfoDivNode.appendChild( document.createTextNode( trancatedVideoInfoStr));

    videoUnitContainer.appendChild( ytVideoInfoDivNode);

    return ytVideoInfoDivNode;
} // function ytTitleDescriptionCommonTask( styleClass, videoInfoStr, videoInfoStrLength, videoUnitContainer)
function clickComsumerOnYtVideoTitle() {
    return false;
} // function clickComsumerOnYtVideoTitle()
function enlistYtVideos( ytData, enlistYtVideosOptions)
{
    // Arguments check ---------------------------------------------------------
    var enlistYtVideosTempVar = null; // Temporary variable for processing support

    // At below, it may consider as redundant to define variables for each sub properties of enlistYtVideosOptions.
    // It's because no guarantee that enlistYtVideosOptions argument is based on enlistYtVideosOptionsMold().
    // Thereby, it's simple and easier to define variable for each sub properties of enlistYtVideosOptions.

    // About videoListContainerId
    var videoListContainerNode = null;
    enlistYtVideosTempVar = ytTrimEdgeSpaceChar( enlistYtVideosOptions.videoListContainerId);
    if ( enlistYtVideosTempVar != null) {
        videoListContainerNode = document.getElementById( enlistYtVideosTempVar);
        if ( videoListContainerNode == null) return;
        if ( videoListContainerNode.nodeType != 1) return;
    }
    // About ytPlayerPlaceHolderId
    var ytPlayerPlaceHolderId = ytTrimEdgeSpaceChar( enlistYtVideosOptions.ytPlayerPlaceHolderId);
    if ( ytPlayerPlaceHolderId != null) {
        enlistYtVideosTempVar = document.getElementById( ytPlayerPlaceHolderId);
        if ( enlistYtVideosTempVar == null) return;
        if ( enlistYtVideosTempVar.nodeType != 1) return;
    }
    // About swfobjAttribs.id
    var playerAPIId = null;
    if ( ( typeof enlistYtVideosOptions.swfobjAttribs).toLowerCase() == "object") {
        if ( enlistYtVideosOptions.swfobjAttribs != null) {
            playerAPIId = ytTrimEdgeSpaceChar( enlistYtVideosOptions.swfobjAttribs.id);
        }
    }

    // About value of behaviorDirector
    // 0: show list of video and player
    // (= videoListContainerId and ytPlayerPlaceHolderId is specified, indifferent on enlistYtVideosOptions.swfobjAttribs.id)
    // 1: show no list of video. Show just player to play (sequence of) video(s)
    // (= videoListContainerId is null, and ytPlayerPlaceHolderId is specified, indifferent on enlistYtVideosOptions.swfobjAttribs.id)
    // enlistYtVideosOptions.swfobjParams.stateChangeHandler must hold value of state change handler function to handle loop play.
    // Otherwise, no point of using this, since that means just going to play one video.
    // Also, highly recommend that enlistYtVideosOptions.swfobjParams.errorHandler holds value of error handler function.
    // 2: show no player but list of video on which click action links to existing player
    // (= videoListContainerId is specified, ytPlayerPlaceHolderId is null, enlistYtVideosOptions.swfobjAttribs.id is specified)
    // In this case, click action will overwrite existing player. Because, otherwise, there will be timming issue hard to manage.
    // 3: show no player but list of video linking to YouTube page
    // (= videoListContainerId is specified, ytPlayerPlaceHolderId is null, enlistYtVideosOptions.swfobjAttribs.id is null)
    // 4: show no player and no list of video, just renew existing player with (sequence of) video(s)
    // (= videoListContainerId and ytPlayerPlaceHolderId are null, enlistYtVideosOptions.swfobjAttribs.id is specified)
    // In this case, renewing means overwritting. Because, otherwise, there will be timming issue hard to manage.
    // Thereby, enlistYtVideosOptions.swfobjParams.stateChangeHandler must hold value of state change handler function to handle loop play.
    // Otherwise, no point of using this, since that means just going to play one video.
    // Also, highly recommend that enlistYtVideosOptions.swfobjParams.errorHandler holds value of error handler function.

    // I may need to consider the case: show list first without player. When one of video in list is clicked, player appears and play video.
    var behaviorDirector = -1;
    if ( ( videoListContainerNode != null) && ( ytPlayerPlaceHolderId != null)) {
        behaviorDirector = 0;
    }
    else if ( ( videoListContainerNode == null) && ( ytPlayerPlaceHolderId != null)) {
        behaviorDirector = 1;
    }
    else if ( ( videoListContainerNode != null) && ( ytPlayerPlaceHolderId == null)) {
        if ( playerAPIId != null) {
            behaviorDirector = 2;
        }
        else {
            behaviorDirector = 3;
        }
    }
    else if ( ( videoListContainerNode == null) && ( ytPlayerPlaceHolderId == null) && ( playerAPIId != null)) {
        behaviorDirector = 4;
    }
    if ( behaviorDirector < 0) return;
    if ( ( behaviorDirector == 1) || ( behaviorDirector == 4)) {
        // enlistYtVideosOptions.swfobjParams.stateChangeHandler must hold value of state change handler function to handle loop play.
        if ( ( typeof enlistYtVideosOptions.swfobjParams).toLowerCase() != "object") return;
        if ( enlistYtVideosOptions.swfobjParams == null) return;
        if ( ytTrimEdgeSpaceChar( enlistYtVideosOptions.swfobjParams.stateChangeHandler) == null) return;
    }
    if ( ( behaviorDirector == 2) || ( behaviorDirector == 4)) {
        // enlistYtVideosOptions.swfobjAttribs.id must point to existing (player) node to overwrite
        enlistYtVideosTempVar = document.getElementById( playerAPIId);
        if ( enlistYtVideosTempVar == null) return;
        if ( enlistYtVideosTempVar.nodeType != 1) return;
    }
    // About videoUnitContainerStyleClass
    var videoUnitContainerStyleClass = ytTrimEdgeSpaceChar( enlistYtVideosOptions.videoUnitContainerStyleClass);

    // About playerWidth
    var playerWidth = 425;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.playerWidth)) {
        if ( enlistYtVideosOptions.playerWidth > 10) {
            playerWidth = enlistYtVideosOptions.playerWidth;
        }
    }
    // About playerHeight
    var playerHeight = 356;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.playerHeight)) {
        if ( enlistYtVideosOptions.playerHeight > 10) {
            playerHeight = enlistYtVideosOptions.playerHeight;
        }
    }
    // About videoNumPerPage
    var videoNumPerPage = 10;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.videoNumPerPage)) {
        if ( enlistYtVideosOptions.videoNumPerPage > 0) {
            videoNumPerPage = enlistYtVideosOptions.videoNumPerPage;
        }
    }
    // About showNaviArrow
    var showNaviArrow = true;
    if ( ytBooleanIntegrityCheck( enlistYtVideosOptions.showNaviArrow)) {
        showNaviArrow = enlistYtVideosOptions.showNaviArrow;
    }
    // About naviArrowStyleClass
    var naviArrowStyleClass = ytTrimEdgeSpaceChar( enlistYtVideosOptions.naviArrowStyleClass);

    // About displayElementOrder
    var displayElementOrderArray = null;
    enlistYtVideosTempVar = ytTrimEdgeSpaceChar( enlistYtVideosOptions.displayElementOrder);
    if ( enlistYtVideosTempVar != null) {
        enlistYtVideosTempVar = enlistYtVideosTempVar.replace( ' ', '', 'g');
        enlistYtVideosTempVar = enlistYtVideosTempVar.toLowerCase();
        displayElementOrderArray = enlistYtVideosTempVar.split( ",");
        var validDisplayElementFlag = false;
        for( var displayElementIndex = 0; displayElementIndex < displayElementOrderArray.length; displayElementIndex++) {
            if ( displayElementOrderArray[ displayElementIndex].search( new RegExp( "^[tTpPdD]$")) > -1) {
                validDisplayElementFlag = true;
                break; // for
            }
        } // for
        if ( !validDisplayElementFlag) {
            displayElementOrderArray = [ "t", "p", "d"];
        }
    }
    else {
        displayElementOrderArray = [ "t", "p", "d"];
    }

    // About thumbnailType
    var thumbnailType = 0;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.thumbnailType)) {
        if ( ( -1 <= enlistYtVideosOptions.thumbnailType) && ( enlistYtVideosOptions.thumbnailType < 4)) {
            thumbnailType = enlistYtVideosOptions.thumbnailType;
        }
    }
    // About thumbnailStyleClass
    var thumbnailStyleClass = ytTrimEdgeSpaceChar( enlistYtVideosOptions.thumbnailStyleClass);

    // About titleLength
    var titleLength = 20;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.titleLength)) {
        if ( enlistYtVideosOptions.titleLength > 0) {
            titleLength = enlistYtVideosOptions.titleLength;
        }
    }
    // About titleStyleClass
    var titleStyleClass = ytTrimEdgeSpaceChar( enlistYtVideosOptions.titleStyleClass);
    
    // About titleInTooltip
    var titleInTooltip = true;
    if ( ytBooleanIntegrityCheck( enlistYtVideosOptions.titleInTooltip)) {
        titleInTooltip = enlistYtVideosOptions.titleInTooltip;
    }
    // About descriptionLength
    var descriptionLength = 20;
    if ( ytNumIntegrityCheck( enlistYtVideosOptions.descriptionLength)) {
        if ( enlistYtVideosOptions.descriptionLength > 0) {
            descriptionLength = enlistYtVideosOptions.descriptionLength;
        }
    }
    // About descriptionStyleClass
    var descriptionStyleClass = ytTrimEdgeSpaceChar( enlistYtVideosOptions.descriptionStyleClass);
    
    // About descriptionInTooltip
    var descriptionInTooltip = true;
    if ( ytBooleanIntegrityCheck( enlistYtVideosOptions.descriptionInTooltip)) {
        descriptionInTooltip = enlistYtVideosOptions.descriptionInTooltip;
    }
    // -------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    var ytFeedEntryArray = ytData.feed.entry || [];
    var ytFeedEntryMaxIndex = ytFeedEntryArray.length;
    if ( ytFeedEntryMaxIndex < 1) return;

    if ( ytFeedEntryMaxIndex > videoNumPerPage) {
        ytFeedEntryMaxIndex = videoNumPerPage;
    }
    // -------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    var ytSwfUrl = null;
    var ytSwfUrlPrefix = "http://www.youtube.com/v/";
    var ytSwfUrlSuffix = "&enablejsapi=1"
    if ( playerAPIId != null) {
        ytSwfUrlSuffix = ytSwfUrlSuffix + "&playerapiid=" + playerAPIId;
    }
    var videoIdListStr = "";
    var ytFeedEntryIndex = 0;
    var ytFeedEntry = null;
    for( ytFeedEntryIndex = 0; ytFeedEntryIndex < ytFeedEntryMaxIndex; ytFeedEntryIndex++) {
        ytFeedEntry = ytFeedEntryArray[ ytFeedEntryIndex];
        if ( ytFeedEntry.media$group.yt$videoid) { // Valid video. Video has not been deleted
            if ( !ytSwfUrl) {
                ytSwfUrl = ytSwfUrlPrefix + ytFeedEntry.media$group.yt$videoid.$t + ytSwfUrlSuffix;
            }
            videoIdListStr = videoIdListStr + ytFeedEntry.media$group.yt$videoid.$t + ",";
        }
    } // for
    videoIdListStr = videoIdListStr.replace( new RegExp( ",$"), "");

    if ( videoIdListStr.length < 1) return; // No valid video was found. So, no point of processing further than here.

    // -------------------------------------------------------------------------

    // Prepare argument of renewYtPlayer which will be called by onclick action event
    // -------------------------------------------------------------------------
    var swfobjParams4RenewYtPlayer = new swfObjParamsMold();
    var swfobjAttribs4RenewYtPlayer = new swfobjAttribsMold();
    if ( ( behaviorDirector == 0) || ( behaviorDirector == 2)) {
        // For newly created YouTube video player, reset video Ids to ones obtained from YouTube video API
        // About other property of swfobjParams, just inherit
        var addedVideoIdsFlag = false;
        if ( ( typeof enlistYtVideosOptions.swfobjParams).toLowerCase() != "undefined") {
            if ( enlistYtVideosOptions.swfobjParams != null) {
                for( var swfobjParamsElementIndex in enlistYtVideosOptions.swfobjParams) {
                    if ( swfobjParamsElementIndex.toLowerCase() == "videoids") {
                        swfobjParams4RenewYtPlayer[ swfobjParamsElementIndex] = videoIdListStr;
                        addedVideoIdsFlag = true;
                    }
                    else {
                        swfobjParams4RenewYtPlayer[ swfobjParamsElementIndex] =
                            enlistYtVideosOptions.swfobjParams[ swfobjParamsElementIndex];
                    }
                } // for
            }
        }
        if ( !addedVideoIdsFlag) swfobjParams4RenewYtPlayer.videoIds = videoIdListStr;

        // For newly created YouTube video player, just inherit swfobjAttribs
        if ( (typeof enlistYtVideosOptions.swfobjAttribs).toLowerCase() != "undefined") {
            if ( typeof enlistYtVideosOptions.swfobjAttribs != null) {
                for( var swfobjAttribsElementIndex in enlistYtVideosOptions.swfobjAttribs) {
                    if ( enlistYtVideosOptions.swfobjAttribs[ swfobjAttribsElementIndex] != null) {
                        swfobjAttribs4RenewYtPlayer[ swfobjAttribsElementIndex] =
                            enlistYtVideosOptions.swfobjAttribs[ swfobjAttribsElementIndex];
                    }
                } // for
            }
        }
    }
    // -------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    for( ytFeedEntryIndex = 0; ytFeedEntryIndex < ytFeedEntryMaxIndex; ytFeedEntryIndex++) {
        ytFeedEntry = ytFeedEntryArray[ ytFeedEntryIndex];
        if ( ( behaviorDirector == 0) || ( behaviorDirector == 2) || ( behaviorDirector == 3)) { // Cases of showing list of videos info
            if ( !ytFeedEntry.media$group.yt$videoid) continue;
            var ytVideoUnitContainerDiv = document.createElement( "div");
            ytVideoUnitContainerDiv.setAttribute( "id", ytFeedEntry.media$group.yt$videoid.$t);
            if ( videoUnitContainerStyleClass != null) ytVideoUnitContainerDiv.className = videoUnitContainerStyleClass;

            var thumbnailImgTag = null;
            var thumbnailImgAlt = "";
            var renewYtPlayerHandler = 
                google.maps.Event.callbackArgs(
                    ytPlayerHandler,
                    ytPlayerHandler.renewYtPlayer,
                    ytSwfUrlPrefix + ytFeedEntry.media$group.yt$videoid.$t + ytSwfUrlSuffix,
                    behaviorDirector,
                    ytPlayerPlaceHolderId,
                    playerWidth, playerHeight,
                    swfobjParams4RenewYtPlayer,
                    swfobjAttribs4RenewYtPlayer
                    );
            var windowOpenHandler =
                google.maps.Event.callbackArgs( window, window.open, ytFeedEntry.media$group.media$player.url);
            for( var elementCharIndex in displayElementOrderArray) {
                switch( displayElementOrderArray[ elementCharIndex]) {
                    case 'p':
                        thumbnailImgTag = document.createElement( "img");
                        thumbnailImgTag.style.cursor = "pointer";
                        if ( thumbnailStyleClass != null) {
                            thumbnailImgTag.className = thumbnailStyleClass;
                        }
                        var thumbnailTypeToUse = thumbnailType;
                        if ( thumbnailTypeToUse == -1) {
                            if ( ytFeedEntry.media$group.media$thumbnail.length < 2) {
                                thumbnailTypeToUse = 0;
                            }
                            else {
                                thumbnailTypeToUse = Math.round( (Math.random() * (ytFeedEntry.media$group.media$thumbnail.length - 2)));
                            }
                        }
                        thumbnailImgTag.setAttribute( "src", ytFeedEntry.media$group.media$thumbnail[ thumbnailTypeToUse].url);
                        if ( ( behaviorDirector == 0) || ( behaviorDirector == 2)) {
//                            thumbnailImgTag.setAttribute( "renewYtPlayerArguments", renewYtPlayerStr);
                            google.maps.Event.addDomListener( thumbnailImgTag, "click", renewYtPlayerHandler);
                        }
                        else if ( behaviorDirector == 3) {
//                            thumbnailImgTag.setAttribute( "onclick", "window.open(" + ytFeedEntry.media$group.media$player.url + ")");
                            google.maps.Event.addDomListener( thumbnailImgTag, "click", windowOpenHandler);
                        }

                        if ( titleInTooltip) {
                            thumbnailImgAlt = "[" + ytFeedEntry.media$group.media$title.$t + "] " + thumbnailImgAlt;
                        }
                        if ( descriptionInTooltip) {
                            thumbnailImgAlt = thumbnailImgAlt + ytFeedEntry.media$group.media$description.$t;
                        }
                        thumbnailImgTag.setAttribute( "title", thumbnailImgAlt);
                        
                        ytVideoUnitContainerDiv.appendChild( thumbnailImgTag);
                        break; // switch
                    case 't':
                        var ytVideoTitleDivNode =
                            ytTitleDescriptionCommonTask(
                                titleStyleClass, ytFeedEntry.media$group.media$title.$t, titleLength, ytVideoUnitContainerDiv
                                );
                        var ytVideoTitleHyperLinkNode = document.createElement( "a");
                        ytVideoTitleHyperLinkNode.appendChild( ytVideoTitleDivNode.firstChild.cloneNode( true));
                        ytVideoTitleHyperLinkNode.setAttribute( "href", "javascript:return( clickComsumerOnYtVideoTitle());");
                        // Setting onclick won't work on FireFox
                        // ytVideoTitleHyperLinkNode.onclick = "dummyOnClickHandlerOnYtVideoTitle";
                        ytVideoTitleDivNode.replaceChild( ytVideoTitleHyperLinkNode, ytVideoTitleDivNode.firstChild);
                        if ( ( behaviorDirector == 0) || ( behaviorDirector == 2)) {
                            google.maps.Event.addDomListener( ytVideoTitleDivNode, "click", renewYtPlayerHandler);
                        }
                        else if ( behaviorDirector == 3) {
                            google.maps.Event.addDomListener( thumbnailImgTag, "click", windowOpenHandler);
                        }
                        break; // switch
                    case 'd':
                        ytTitleDescriptionCommonTask(
                            descriptionStyleClass, ytFeedEntry.media$group.media$description.$t, descriptionLength, ytVideoUnitContainerDiv
                            );
                        break; // switch
                } // switch
            } // for
            //ytVideoUnitContainerDiv.setAttribute( "onload", "loadYtVideo( this)");
            videoListContainerNode.appendChild( ytVideoUnitContainerDiv);
        }
    } // for
    // -------------------------------------------------------------------------
    // -------------------------------------------------------------------------
    if ( behaviorDirector != 3) {
        // Cases related to player. In other words, it's case other than the following:
        // 3: show no player but list of video linking to YouTube page
        // (= videoListContainerId is specified, ytPlayerPlaceHolderId is null, enlistYtVideosOptions.swfobjAttribs.id is null)

        enlistYtVideosOptions.swfobjParams.videoIds = videoIdListStr;
        swfobject.embedSWF(
            ytSwfUrl, ytPlayerPlaceHolderId, playerWidth.toString(), playerHeight.toString(),
            '8', null, null, enlistYtVideosOptions.swfobjParams, enlistYtVideosOptions.swfobjAttribs
            );
    }
    // -------------------------------------------------------------------------

} // function enlistYtVideos( ytData, enlistYtVideosOptions)

function getCordinate( domNode) {
  if( (typeof domNode.offsetParent).toLowerCase() != 'undefined' ) {
    for( var posX = 0, posY = 0; domNode; domNode = domNode.offsetParent ) {
      posX += domNode.offsetLeft;
      posY += domNode.offsetTop;
    } // for
    return [ posX, posY ];
  } else {
    return [ domNode.x, domNode.y ];
  }
} // getCordinate( domNode)

function addYtPlayerCloserNode( ytPlayerId) {
    var ytPlayerNodeObj = document.getElementById( ytPlayerId);
    if ( (typeof ytPlayerNodeObj).toLowerCase() == "object") {
        if ( ytPlayerNodeObj != null) {
            if ( ytPlayerNodeObj.nodeType == 1) {
                var ytPlayerCloserChildNode = document.createElement( "div");
                ytPlayerCloserChildNode.style.width = "1em";
                ytPlayerCloserChildNode.style.cursor = "pointer";
                ytPlayerCloserChildNode.style.color = "red";
                ytPlayerCloserChildNode.style.styleFloat = "right";
                ytPlayerCloserChildNode.style.cssFloat = "right";
                ytPlayerCloserChildNode.setAttribute( "title", "Close");
                ytPlayerCloserChildNode.appendChild( document.createTextNode( "\u2297"));
                var ytPlayerCloserNode = document.createElement( "div");
            }
        }
    }
} // function addYtPlayerCloserNode( ytPlayerId)
