var BCLSVJS = (function (window, document, docData, hljs) {
    'use strict';
    var title = document.getElementsByTagName('title')[0],
        // data structures
        classes = {thisClass: [], parentClass: []},
        doc_class,
        docsPath = 'https://github.com/videojs/video.js/blob/master/src/js/',
        doc_data = {},
        // doc path as an array
        path = document.location.pathname.split('/'),
        // paths
        classFilePath,
        parentClassFilePath,
        // elements
        mainContent,
        main,
        doc_body = document.getElementsByTagName('body')[0],
        // functions
        isDefined,
        isItemInArray,
        copyObj,
        findObjectInArray,
        findObjectsInArray,
        getSubArray,
        sortArray,
        createEl,
        bclslog,
        findClassObjects,
        addHeaderContent,
        addIndex,
        addMembersContent,
        addText,
        highlightCode,
        init;
    /**
     * Logging function - safe for IE
     *
     * @param  {string} context - description of the data
     * @param  {*} message - the data to be logged by the console
     */
    bclslog = function (context, message) {
        if (window['console'] && console['log']) {
            console.log(context, message);
        }
    };
    /**
     * tests for all the ways a variable might be undefined or not have a value
     *
     * @param {*} x the variable to test
     * @return {Boolean} true if variable is defined and has a value
     */
    isDefined = function (x) {
        if (x === '' || x === null || x === undefined || x === NaN) {
            return false;
        }
        return true;
    };
    /**
     * determines whether specified item is in an array
     *
     * @param {array} array to check
     * @param {string} item to check for
     * @return {boolean} true if item is in the array, else false
     */
    isItemInArray = function (arr, item) {
        var i,
            iMax = arr.length;
        for (i = 0; i < iMax; i++) {
            if (arr[i] === item) {
                return true;
            }
        }
        return false;
    };
    /**
     * get a copy of (rather than reference to) an object
     *
     * @param  {object} obj - the object you want a copy
     * @return {object}     the copy
     */
    copyObj = function (obj) {
        if (isDefined(obj)) {
            return JSON.parse(JSON.stringify(obj));
        }
        bclslog('no obj passed');
    };
    /**
     * find index of an object in array of objects
     * based on some property value
     * generally useful for finding a unique object
     *
     * @param {array} targetArray - array to search
     * @param {string} objProperty - object property to search
     * @param {string|number} value - value of the property to search for
     * @return {integer} index of first instance if found, otherwise returns -1
     */
    findObjectInArray = function (targetArray, objProperty, value) {
        var i, totalItems = targetArray.length, objFound = false;
        for (i = 0; i < totalItems; i++) {
            if (targetArray[i][objProperty] === value) {
                objFound = true;
                return i;
            }
        }
        if (objFound === false) {
            return -1;
        }
    };
    /**
     * find indexes of a set of object in array of objects
     * based on some property value
     * generally useful for finding several objects
     *
     * @param {array} targetArray - array to search
     * @param {string} objProperty - object property to search
     * @param {string|number} value - value of the property to search for
     * @return {array} array of indexes for matching objects
     */
    findObjectsInArray = function (targetArray, objProperty, value) {
        var i, totalItems = targetArray.length, newArr = [];
        for (i = 0; i < totalItems; i++) {
            if (targetArray[i][objProperty] === value) {
                newArr.push(i);
            }
        }
        return newArr;
    };
    /**
     * get a subset of objects in array of objects
     * based on some property value
     *
     * @param {array} targetArray - array to search
     * @param {string} objProperty - object property to search
     * @param {string|number} value - value of the property to search for
     * @return {array} array of objects with matching property value
     */
    getSubArray = function (targetArray, objProperty, value) {
        var i, totalItems = targetArray.length, idxArr = [];
        for (i = 0; i < totalItems; i++) {
            if (targetArray[i][objProperty] === value) {
                idxArr.push(targetArray[i]);
            }
        }
        return idxArr;
    };
    /**
     * sort an array of objects based on an object property
     *
     * @param {array} targetArray - array to sort
     * @param {string} objProperty - property whose value to sort on
     * @return {array} the sorted array
     */
    sortArray = function (targetArray, objProperty) {
        targetArray.sort(function (a, b) {
            var propA = a[objProperty].toLowerCase(), propB = b[objProperty].toLowerCase();
            // sort ascending; reverse propA and propB to sort descending
            if (propA < propB) {
                return -1;
            } else if (propA > propB) {
                return 1;
            }
            return 0;
        });
        return targetArray;
    };
    /**
     * create an element
     *
     * @param  {string} type - the element type
     * @param  {object} attributes - attributes to add to the element
     * @return {object} the HTML element
     */
    createEl = function (type, attributes) {
        var el;
        if (isDefined(type)) {
            el = document.createElement(type);
            if (isDefined(attributes)) {
                var attr;
                for (attr in attributes) {
                    el.setAttribute(attr, attributes[attr]);
                }
            }
            return el;
        }
    };
    /**
     * creates a text node and adds it to an element
     * @param {object|node} el - the node (element) to add the text to
     * @param {string} str - the text to add
     */
    addText = function (el, str) {
        var text = document.createTextNode(str);
        el.appendChild(text);
    };
    /**
     * finds the objects in the doc data for a fileName
     *
     * @param {array} arr - the array of objects to search
     * @param {string} filename - the filename to look for in the meta object
     * @return {array} - array of the objects found
     */
    findClassObjects = function (arr, filename) {
        var i, totalItems = arr.length, newArr = [];
        for (i = 0; i < totalItems; i++) {
            if (isDefined(arr[i].meta)) {
                if (arr[i].meta.filename === filename) {
                    newArr.push(arr[i]);
                }
            }

        }
        return newArr;

    };
    /**
     * add the class header content
     */
    addHeaderContent = function () {
        var topSection = createEl('section', {id: 'top', class: 'section'}),
            headerData = doc_data.thisClass.headerInfo,
            header = createEl('h1'),
            extendsNode = createEl('p'),
            extendsLink,
            definedIn = createEl('p'),
            definedInLink = createEl('a', {href: docsPath + classFilePath + '#L' + headerData.meta.lineno}),
            description = createEl('div', {style: 'border:none', id: 'classDescription'}),
            descriptionEl,
            constructorHeader = createEl('h3'),
            constructorPre = createEl('pre'),
            constructorCode = createEl('code'),
            constructorParamsHeader = createEl('h4'),
            constructorParams = [],
            text;
        // add main content wrapper
        doc_body.appendChild(mainContent);
        main = document.getElementById('main');
        // add elements
        topSection.appendChild(header);
        topSection.appendChild(description);
        // source file
        topSection.appendChild(definedIn);
        addText(definedIn, 'DEFINED IN: ');
        definedIn.appendChild(definedInLink);
        addText(definedInLink, headerData.meta.filename + ' line number: ' + headerData.meta.lineno);
        mainContent.appendChild(topSection);
        // page header
        addText(header, headerData.name);
        // parent info if this class extends another
        if (isDefined(doc_data.parentClasses)) {
            topSection.appendChild(extendsNode);
            addText(extendsNode, 'EXTENDS: ');
            extendsLink = createEl('a', {href: parentClassFilePath + doc_data.parentClasses[0].headerInfo.meta.filename});
            extendsNode.appendChild(extendsLink);
            addText(extendsLink, doc_data.parentClasses[0].headerInfo.meta.filename);
        }
        // constructor info - don't add for video.js
        if (doc_data.thisClass.headerInfo.name !== 'videojs') {
            topSection.appendChild(constructorHeader);
            topSection.appendChild(constructorPre);
            constructorPre.appendChild(constructorCode);
            // create the constructor info
            addText(constructorHeader, 'Constructor');

            // get constructor params if any
            if (isDefined(headerData.params)) {
                var paramTableHeaders = ['name', 'Type', 'Required', 'Description'],
                    paramTable = createEl('table'),
                    paramThead = createEl('thead'),
                    paramTbody = createEl('tbody'),
                    paramTheadRow = createEl('tr'),
                    paramTbodyRow = createEl('tr'),
                    paramTH,
                    paramTD,
                    k,
                    kMax;

                addText(constructorParamsHeader, 'Parameters');
                paramTable.appendChild(paramThead);
                paramTable.appendChild(paramTbody);
                paramThead.appendChild(paramTheadRow);
                // set the table headers
                kMax = paramTableHeaders.length;
                for (k = 0; k < kMax; k++) {
                    paramTH = createEl('th');
                    paramTheadRow.appendChild(paramTH);
                    addText(paramTH, paramTableHeaders[k]);
                }
                // now the table info
                kMax = headerData.params.length;
                for (k = 0; k < kMax; k++) {
                    paramTbodyRow = createEl('tr');
                    paramTbody.appendChild(paramTbodyRow);
                    paramTD = createEl('td');
                    addText(paramTD, headerData.params[k].name);
                    paramTbodyRow.appendChild(paramTD);
                    paramTD = createEl('td');
                    addText(paramTD, headerData.params[k].type.names.join('|'));
                    paramTbodyRow.appendChild(paramTD);
                    paramTD = createEl('td');
                    if (headerData.params[k].optional) {
                        text = document.createTextNode('no');
                        constructorParams.push('[' + headerData.params[k].name + ']');
                    } else {
                        text = document.createTextNode('yes');
                        constructorParams.push(headerData.params[k].name);
                    }
                    paramTD.appendChild(text);
                    if (isDefined(headerData.params[k].description)) {
                        paramTbodyRow.appendChild(paramTD);
                        paramTD = createEl('td');
                        addText(paramTD, headerData.params[k].description.slice(3, headerData.params[k].description.indexOf('</p>')));
                        paramTbodyRow.appendChild(paramTD);
                    }
                    paramTbody.appendChild(paramTbodyRow);
                }
                topSection.appendChild(constructorParamsHeader);
                topSection.appendChild(paramTable);
            }
        }
        // add constructor params to signature if any
        if (constructorParams.length > 0) {
            text = document.createTextNode(headerData.name + '( ' + constructorParams.join(',') + ' )');
        } else {
            text = document.createTextNode(headerData.name + '()');
        }
        constructorCode.appendChild(text);
        descriptionEl = document.getElementById('classDescription');
        descriptionEl.innerHTML = headerData.description;
    };
    /**
     * add the side nav
     */
    addIndex = function () {
        var section = createEl('section', {id: 'index', class: 'side-nav'}),
            navHeader = createEl('h2', {class: 'sideNavHeader'}),
            navHeaderLink = createEl('a', {href: 'index.html'}),
            memberIndex = createEl('div', {id: 'memberIndex', class: 'member-index'}),
            thisMember,
            addedMembers = {},
            item,
            thisParent,
            parentList,
            header,
            listItem,
            listLink,
            classHeader,
            parentHeader,
            i,
            iMax,
            j,
            jMax,
            // helper functions
            classHasMembers = function (member) {
                if (doc_data.thisClass[member].length > 0) {
                    return true;
                }
                return false;
            },
            parentsHaveMembers = function () {
                if (doc_data.parentClasses.length > 0) {
                    for (i = 0; i < doc_data.parentClasses.length; i++) {
                        if (doc_data.parentClasses[i][thisMember].length > 0) {
                            return true;
                        }
                    }
                    return false;
                }
            },
            makeList = function (classArr, parentArr, member, list) {
                thisMember = member.toLowerCase();
                if (classArr.length > 0 || (isDefined(doc_data.parentClass) && parentArr.length > 0)) {
                    // add member list header
                    if (classHasMembers(thisMember) || parentsHaveMembers(thisMember)) {
                        header = createEl('h3');
                        addText(header, doc_data.thisClass.headerInfo.name + ' ' + member);
                    } else {
                        return;
                    }
                    if (classHasMembers(thisMember)) {
                        classHeader = createEl('h4');
                        addText(classHeader, 'Class ' + member);
                        memberIndex.appendChild(header);
                        memberIndex.appendChild(classHeader);
                        // add the list & items
                        list = createEl('ul', {id: list});
                        memberIndex.appendChild(list);
                        iMax = classArr.length;
                        for (i = 0; i < iMax; i++) {
                            item = classArr[i].name;
                            if (!isItemInArray(addedMembers[member], item)) {
                                // keep track of added members to remove overridden ones
                                addedMembers[member].push(item);
                                listItem = createEl('li');
                                listLink = createEl('a', {href: '#' + member + item});
                                addText(listLink, item);
                                listItem.appendChild(listLink);
                                list.appendChild(listItem);
                            }
                        }
                    }

                    // add inherited items if any
                    if (isDefined(parentArr) && parentArr.length > 0) {
                        jMax = parentArr.length;
                        for (j = 0; j < jMax; j++) {
                            thisParent = parentArr[j];
                            if (thisParent[thisMember].length > 0) {
                                parentHeader = createEl('h4');
                                addText(parentHeader, 'Inherited ' + member + ' from ' + thisParent.headerInfo.name);
                                memberIndex.appendChild(parentHeader);
                                parentList = createEl('ul');
                                memberIndex.appendChild(parentList);
                                iMax = thisParent[thisMember].length;
                                for (i = 0; i < iMax; i++) {
                                    item = thisParent[thisMember][i].name;
                                    if (!isItemInArray(addedMembers[member], item)) {
                                        addedMembers[member].push(item);
                                        listItem = createEl('li');
                                        listLink = createEl('a', {href: '#' + member + item});
                                        listItem.appendChild(listLink);
                                        addText(listLink, item);
                                        parentList.appendChild(listItem);
                                    }

                                }
                            }

                        }

                    }
                }
            };
        // data structure to track members already added
        addedMembers.Methods = [];
        addedMembers.Properties = [];
        addedMembers.Events = [];

        navHeader.appendChild(navHeaderLink);
        addText(navHeaderLink, 'API Index');
        // add parent class members if any
        if (isDefined(doc_data.parentClasses)) {
            makeList(doc_data.thisClass.properties, doc_data.parentClasses, 'Properties', 'propertiesList');
            makeList(doc_data.thisClass.methods, doc_data.parentClasses, 'Methods', 'methodsList');
            makeList(doc_data.thisClass.events, doc_data.parentClasses, 'Events', 'eventsList');
        } else {
            makeList(doc_data.thisClass.properties, [], 'Properties', 'propertiesList');
            makeList(doc_data.thisClass.methods, [], 'Methods', 'methodsList');
            makeList(doc_data.thisClass.events, [], 'Events', 'eventsList');
        }
        section.appendChild(navHeader);
        section.appendChild(memberIndex);
        doc_body.appendChild(section);

    };
    /**
     * add the member content
     */
    addMembersContent = function () {
        var members = [{name: 'Properties', data: 'properties'}, {name: 'Methods', data: 'methods'}, {name: 'Events', data: 'events'}],
            member,
            addedMembers = {},
            section,
            header,
            headerSuffix,
            item,
            itemWrapper,
            itemHeader,
            itemHeaderStr,
            itemParams = [],
            itemParamsHeader,
            itemDescription,
            itemDescriptionEl,
            itemFooter,
            itemFooterLink,
            itemFooterContent,
            paramTable,
            paramThead,
            paramTbody,
            paramTheadRow,
            paramTbodyRow,
            paramTH,
            paramTD,
            paramTableHeaders = ['name', 'Type', 'Required', 'Description'],
            text,
            i,
            iMax,
            j,
            jMax,
            k,
            kMax,
            m,
            mMax,
            topLinkP,
            topLinkA,
            // helper function
            createMemberItem = function (classData, member) {
                bclslog('member', member);
                // create the class member items
                jMax = classData[member.data].length;
                for (j = 0; j < jMax; j++) {
                    item = classData[member.data][j];
                    if (!isItemInArray(addedMembers[member.name], item.name)) {
                        addedMembers[member.name].push(item.name);
                        itemWrapper = createEl('div', {id: member.name + item.name});
                        section.appendChild(itemWrapper);
                        itemHeader = createEl('h3', {id: item.name + 'Header'});
                        itemHeaderStr = item.name;
                        itemWrapper.appendChild(itemHeader);
                        itemDescription = createEl('div', {id: item.name + 'Description', class: 'description'});
                        itemWrapper.appendChild(itemDescription);
                        itemFooter = createEl('p', {class: 'vjs-only'});
                        itemFooterLink = createEl('a', {href: docsPath + item.meta.filename + '#L' + item.meta.lineno});
                        itemFooterContent = createEl('em', {id: item.name + 'Footer'});
                        itemFooter.appendChild(itemFooterContent);
                        topLinkP = createEl('p');
                        topLinkA = createEl('a', {href: '#top'});
                        addText(topLinkA, '[back to top]');
                        topLinkP.appendChild(topLinkA);
                        // for methods only handle params if any
                        if (member.name === 'Methods' && isDefined(item.params)) {
                            itemParams = [];
                            itemParamsHeader = createEl('h4');
                            addText(itemParamsHeader, 'Parameters');
                            paramTable = createEl('table');
                            paramThead = createEl('thead');
                            paramTbody = createEl('tbody');
                            paramTable.appendChild(paramThead);
                            paramTable.appendChild(paramTbody);
                            paramTheadRow = createEl('tr');
                            paramThead.appendChild(paramTheadRow);
                            // set the table headers
                            kMax = paramTableHeaders.length;
                            for (k = 0; k < kMax; k++) {
                                paramTH = createEl('th');
                                paramTheadRow.appendChild(paramTH);
                                addText(paramTH, paramTableHeaders[k]);
                            }
                            // now the table info
                            kMax = item.params.length;
                            for (k = 0; k < kMax; k++) {
                                paramTbodyRow = createEl('tr');
                                paramTbody.appendChild(paramTbodyRow);
                                paramTD = createEl('td');
                                addText(paramTD, item.params[k].name);
                                paramTbodyRow.appendChild(paramTD);
                                paramTD = createEl('td');
                                addText(paramTD, item.params[k].type.names.join('|'));
                                paramTbodyRow.appendChild(paramTD);
                                paramTD = createEl('td');
                                if (item.params[k].optional) {
                                    text = document.createTextNode('no');
                                    itemParams.push('[' + item.params[k].name + ']');
                                } else {
                                    text = document.createTextNode('yes');
                                    itemParams.push(item.params[k].name);
                                }
                                paramTD.appendChild(text);
                                if (isDefined(item.params[k].description)) {
                                    paramTbodyRow.appendChild(paramTD);
                                    paramTD = createEl('td');
                                    addText(paramTD, item.params[k].description.slice(3, item.params[k].description.indexOf('</p>')));
                                    paramTbodyRow.appendChild(paramTD);
                                }
                                paramTbody.appendChild(paramTbodyRow);
                            }
                            itemHeaderStr += '( ' + itemParams.join(', ') + ' )';
                            if (item.scope === 'static') {
                                itemHeaderStr = 'static ' + itemHeaderStr;
                            }
                            itemWrapper.appendChild(itemParamsHeader);
                            itemWrapper.appendChild(paramTable);
                        } else if (member.name === 'Methods') {
                            itemHeaderStr += '()';
                        }
                        itemWrapper.appendChild(itemFooter);
                        itemWrapper.appendChild(topLinkP);
                        addText(itemHeader, itemHeaderStr);
                        if (isDefined(item.deprecated)) {
                            headerSuffix = createEl('em', {class: 'deprecated'});
                            text = document.createTextNode();
                            addText(headerSuffix, ' (deprecated)');
                            itemHeader.appendChild(headerSuffix);
                        }
                        itemDescriptionEl = document.getElementById(item.name + 'Description');
                        itemDescriptionEl.innerHTML = item.description;
                        addText(itemFooterContent, 'Defined in ');
                        itemFooterContent.appendChild(itemFooterLink);
                        addText(itemFooterLink, 'src/js/' + item.meta.filename + ' line number: ' + item.meta.lineno);
                    }
                }
            };
        // data structure to track members already added
        addedMembers.Methods = [];
        addedMembers.Properties = [];
        addedMembers.Events = [];
        iMax = members.length;
        for (i = 0; i < iMax; i++) {
            member = members[i];
            if (doc_data.thisClass[member.data].length > 0) {
                // create the member section
                section = createEl('section', {id: member.name.toLowerCase(), class: 'section'});
                main.appendChild(section);
                header = createEl('h2');
                addText(header, member.name);
                section.appendChild(header);
                // create the member items
                createMemberItem(doc_data.thisClass, member);
                if (isDefined(doc_data.parentClasses)) {
                    mMax = doc_data.parentClasses.length;
                    for (m = 0; m < mMax; m++) {
                        if (doc_data.parentClasses[m][member.data].length > 0) {
                            createMemberItem(doc_data.parentClasses[m], member);
                        }
                    }
                }
            }
        }
    };
    /**
     * use hljs to highlight the syntax in code blocks
     */
    highlightCode = function () {
        var codeBlocks = document.querySelectorAll('pre code'),
            i,
            iMax;
        if (isDefined(codeBlocks)) {
            iMax = codeBlocks.length;
            for (i = 0; i < iMax; i++) {
                hljs.highlightBlock(codeBlocks[i]);
            }
        }
    };
    /**
     * init gets things going
     */
    init = function () {
        var fileName,
            srcFileName,
            parent_class_name,
            privateItems = [],
            idx,
            text,
            j,
            parentCounter = 0,
            // helper function to get the chain of parent classes
            getAncestorData = function (parent_class) {
                // get data objects for the class
                classes.parentClasses[parentCounter] = findClassObjects(docData, parent_class + '.js');
                // check to see if there are any parent class items
                if (classes.parentClasses[parentCounter].length > 0) {
                    doc_data.parentClasses[parentCounter] = {};
                    // get parent header info
                    idx = findObjectInArray(classes.parentClasses[parentCounter], 'kind', 'class');
                    doc_data.parentClasses[parentCounter].headerInfo = copyObj(classes.parentClasses[parentCounter][idx]);
                    // get parent class path
                    idx = findObjectInArray(classes.parentClasses[parentCounter], 'kind', 'file');
                    if (idx > -1) {
                        parentClassFilePath = classes.parentClasses[parentCounter][idx].name;
                    } else {
                        parentClassFilePath = doc_data.parentClasses[parentCounter].headerInfo.meta.filename;
                    }
                    // remove any private items
                    privateItems = findObjectsInArray(classes.parentClasses[parentCounter], 'access', 'private');
                    j = privateItems.length;
                    while (j > 0) {
                        j--;
                        classes.parentClasses[parentCounter].splice(privateItems[j], 1);
                    }
                    // now get the member arrays
                    doc_data.parentClasses[parentCounter].methods = getSubArray(classes.parentClasses[parentCounter], 'kind', 'function');
                    doc_data.parentClasses[parentCounter].methods = sortArray(doc_data.parentClasses[parentCounter].methods, 'name');
                    doc_data.parentClasses[parentCounter].events = getSubArray(classes.parentClasses[parentCounter], 'kind', 'event');
                    doc_data.parentClasses[parentCounter].events = sortArray(doc_data.parentClasses[parentCounter].events, 'name');
                    doc_data.parentClasses[parentCounter].properties = getSubArray(classes.parentClasses[parentCounter], 'kind', 'property');
                    doc_data.parentClasses[parentCounter].properties = sortArray(doc_data.parentClasses[parentCounter].properties, 'name');
                }
                // get parent class, if any, and anything it inherits
                if (isDefined(doc_data.parentClasses[parentCounter].headerInfo.augments)) {
                    idx = findObjectInArray(docData, 'name', doc_data.parentClasses[parentCounter].headerInfo.augments[0]);
                    parent_class_name = docData[idx].meta.filename.replace('.js', '');
                    parentCounter++;
                    getAncestorData(parent_class_name);
                }
            };
        // content wrapper
        mainContent = createEl('div', {id: 'main', class: 'section'});
        // get the class name from the file name
        fileName = path[path.length - 1];
        doc_class = fileName.substring(0, fileName.indexOf('.'));
        srcFileName = doc_class + '.js';
        bclslog('srcFileName', srcFileName);
        // video.js is a special case - all others will be the same
        if (srcFileName === 'video.js') {
            // for doc purposes, treat video like a class, though it's not
            // get the data objects for this class
            classes.thisClass = findClassObjects(docData, srcFileName);
            bclslog('classes', classes);
            idx = findObjectInArray(classes.thisClass, 'name', 'videojs');
            doc_data.thisClass = {};
            // get the class overview object
            doc_data.thisClass.headerInfo = copyObj(classes.thisClass[idx]);
            doc_data.thisClass.headerInfo.name = 'videojs';
            idx = findObjectInArray(classes.thisClass, 'kind', 'file');
            if (idx > -1) {
                classFilePath = classes.thisClass[idx].name;
            } else {
                classFilePath = doc_data.thisClass.headerInfo.meta.filename;
            }
            // set the doc title
            text = document.createTextNode(doc_data.thisClass.headerInfo.name);
            title.appendChild(text);
            // remove any private items
            privateItems = findObjectsInArray(classes.thisClass, 'access', 'private');
            j = privateItems.length;
            while (j > 0) {
                j--;
                classes.thisClass.splice(privateItems[j], 1);
            }
            // now get the member arrays
            doc_data.thisClass.methods = getSubArray(classes.thisClass, 'kind', 'function');
            doc_data.thisClass.methods = sortArray(doc_data.thisClass.methods, 'name');
            doc_data.thisClass.events = getSubArray(classes.thisClass, 'kind', 'event');
            doc_data.thisClass.events = sortArray(doc_data.thisClass.events, 'name');
            doc_data.thisClass.properties = getSubArray(classes.thisClass, 'kind', 'property');
            doc_data.thisClass.properties = sortArray(doc_data.thisClass.properties, 'name');
            bclslog('thisClass', doc_data.thisClass);
        } else {
            // get the data objects for this class
            classes.thisClass = findClassObjects(docData, srcFileName);
            bclslog('classes', classes);
            idx = findObjectInArray(classes.thisClass, 'kind', 'class');
            doc_data.thisClass = {};
            doc_data.thisClass.headerInfo = copyObj(classes.thisClass[idx]);
            // get the file path from @file object
            idx = findObjectInArray(classes.thisClass, 'kind', 'file');
            if (idx > -1) {
                classFilePath = classes.thisClass[idx].name;
            } else {
                classFilePath = doc_data.thisClass.headerInfo.meta.filename;
            }
            // set the doc title
            text = document.createTextNode(doc_data.thisClass.headerInfo.name);
            title.appendChild(text);
            // remove any private items
            privateItems = findObjectsInArray(classes.thisClass, 'access', 'private');
            j = privateItems.length;
            while (j > 0) {
                j--;
                classes.thisClass.splice(privateItems[j], 1);
            }
            // now get the member arrays
            doc_data.thisClass.methods = getSubArray(classes.thisClass, 'kind', 'function');
            doc_data.thisClass.methods = sortArray(doc_data.thisClass.methods, 'name');
            doc_data.thisClass.events = getSubArray(classes.thisClass, 'kind', 'event');
            doc_data.thisClass.events = sortArray(doc_data.thisClass.events, 'name');
            doc_data.thisClass.properties = getSubArray(classes.thisClass, 'kind', 'property');
            doc_data.thisClass.properties = sortArray(doc_data.thisClass.properties, 'name');
            bclslog('thisClass', doc_data.thisClass);
            // get parent class, if any, and anything it inherits
            if (isDefined(doc_data.thisClass.headerInfo.augments)) {
                doc_data.parentClass = {};
                doc_data.parentClasses = [];
                classes.parentClasses = [];
                idx = findObjectInArray(docData, 'name', doc_data.thisClass.headerInfo.augments[0]);
                parent_class_name = docData[idx].meta.filename.replace('.js', '');
                getAncestorData(parent_class_name);
            }
            bclslog('parentClasses', doc_data.parentClasses);
        }
        // now we're ready to roll
        addIndex();
        addHeaderContent();
        addMembersContent();
        highlightCode();
    };
    // initialize
    init();
    return {

    };
})(window, document, docData, hljs);