var sghe = (function(sghe) {
    jQuery.getScript( 'https://commons.sungardhe.com/edu1world/workflow_ui?src=' + escape(document.URL) );
    sghe.log = function(args) {};

    jQuery( function() {
        var username = jQuery( "li.mysite a" ).attr("href");
        sghe.username = username && username.replace( /\/blog\/([^/]+)\/home\//, '$1' );
        var debugLog = sghe.username=='KevinButler';

        if ( debugLog && window.console && console.log ) {
            if (jQuery.browser.msie ) {
                sghe.log = function() { console.log( [].join.call(arguments, ', ')); }
            } else {
                sghe.log = function() { console.log(arguments); }
            }
        } else if ( debugLog ) {
            sghe.log = function() {
                if (!jQuery( "#logdiv" ).size()) {
                    jQuery( "#sgheworkflow" ).prepend( jQuery( "<div id='logdiv'>Debug log<br/></div>" ));
                };
                jQuery("#logdiv").append( [].join.call(arguments, ', ') + "<br/>" );
            }
        }

        sghe.log( 'https://commons.sungardhe.com/edu1world/workflow_ui?src=' + document.URL );
        var communityURL = document.URL.match(/.*edu1world.org\/[^\/]+/) + '/';

        // main title thinking outside the box
        var $commtitle = jQuery('#page-description h2.comm-title');
        $commtitle.parent().before($commtitle);

        ////////// Collaboration Wiki -> Wiki
        $('#nav .primary li a span.innerWrap:contains(Collaboration Wiki)').html('Wiki');

        ////////// add commons home, help, and see all
        var linkTemplate = function(URL,NAME) {
            return '<li><a href="URL"><span class="wrap"><span class="innerWrap">NAME</span></span></a></li>'.replace( 'URL', URL ).replace('NAME',NAME);
        }
        var seeAll = jQuery(linkTemplate('#','All Communities'));
        jQuery('#nav .primary ul').
            prepend( linkTemplate('/CommonsSunGardHE/', 'Commons Home' )).
            append( seeAll );

        jQuery('#top-nav ul.secondary').append( linkTemplate('/CommonsSunGardHE/pages/page/?pgid=84" target="_blank', 'Commons Help'));

        seeAll.click( function() { jQuery('#sghenavpopup').toggle(); return false; } );
        jQuery( 'div.sgheclose' ).click( function() { jQuery('#sghenavpopup').toggle(false); return false; } );

        // add nav separator
        jQuery('#nav .primary ul li:not(:first) a').before('<span style="margin-left:6px;margin-right:2px"> | </span>');
        jQuery('#nav .primary li').css('margin-right','0px');

        var savedPostsUrl = communityURL + 'pages/user/favorites/';
        var favoriteCommunities = $('#nav-user-groups>ul>li>ul');
        var favoritesLink = $('#navUserGroupsLink');
        var numFavoriteCommunities = favoriteCommunities.find('li').size();
        if (!numFavoriteCommunities) {
            // add the list, because we need it, even if edu1world didn't
            favoritesLink.after('<ul>');
            favoriteCommunities = $('#nav-user-groups>ul>li>ul'); // refresh
        }

        favoriteCommunities.
            prepend($('#nav-user-groups>ul>li:first').addClass('sghebottomborder'))/*DISABLED: .
            prepend('<li id="sghesavedposts"><a href="' + communityURL + 'pages/user/favorites/">My saved posts in this community</a></li>');*/

        function handleSavedPosts(data) {
            var saved = $('.saved-posts .post .entry-title a', data);
            var numSaved = saved.size();
            favoritesLink.text(favoritesLink.text() + ': ' + /*DISABLED: numSaved + '/' + */ numFavoriteCommunities + '');

            var posts = numSaved == 1 ? 'post' : 'posts';
            var communities = numFavoriteCommunities == 1 ? 'community' : 'communities';
            var tooltip = 'You have ' + /*DISABLED:numSaved + ' ' + posts + ' saved in this community and ' + */ numFavoriteCommunities + ' favorite ' + communities;
            favoritesLink.attr('title', tooltip);

            var postList = $('#sghesavedposts');//.append('<ul>').find('ul');
            saved.each(function(idx,it) {
                var postLink = $('<li class="sghesavedpost">').append($(it).clone());
                sghe.log('found saved post:', postLink);
                postList.append(postLink);
            });
        }

        //DISABLED:jQuery.get(savedPostsUrl, handleSavedPosts);
        handleSavedPosts('disabled for now');

        // add our own Featured Posts title
        $('.featured-posts h2').addClass('comm-title').removeClass('title').find('.innerWrap').text('Featured Posts').toggle(true);

        // move left-hand column to right-hand column, and start it with Start a Discussion
        $('#sb-2>.wrapper').prepend($('#sb-1>.wrapper').children()).prepend($('.section.share-with-us'));
        $('.layout-scs #content').css({
            'margin-left':'0',
            'width':'786px'
        });

        // add a top border to any modules that don't have a title. They won't be collapsible.
        $('#sb-2 div.section.custom-content').each(function(idx,ele) {
            var e = $(ele);
            if (!e.find('h2').size()) {
                $(ele).find('div.content').addClass('sghetopborder');
            }
        });

        sghe.log('adjust search');
        if ($('#ctl00_phMain_rmpSearch').size() == 0) { // except on search results page
            $('#main-search').toggle(false); // hide central search
        }

        var LOCAL = '0';
        var GLOBAL = '1';
        var PROFILES = '2';
        var TOPICS = '3';

        var EDU1_CONTENT = '0';
        var EDU1_TOPICS = '1';
        var EDU1_PROFILES = '2';
        var EDU1_LOCAL = '0';
        var EDU1_GLOBAL = '1';

        var sgheSearch = [
            '<div class="section custom-content" id="sghesearchmodule"><h2 class="title">Search</h2>',
            '<div class="content">',
            '<div id="sgheSearch">',
            '<table><tr><td><input name="sgheSearchText" type="text" class="text" id="sgheSearchText" size="21"></input></td>',
            '<td><input name="sgheSearchImage" type="image" id="sgheSearchImage" src="http://commons.sungardhe.com/static/images/sghe_search_btn.png" alt="Search" class="image-button"></input></td></tr></table>',
            '<select name="sgheSearchIn" id="sgheSearchIn">',
            '  <option value="' + LOCAL + '" selected="">This Community</option>',
            '  <option value="' + GLOBAL + '">All Communities</option>',
            '  <option value="' + PROFILES + '">Personal Profiles</option>',
            '  <option value="' + TOPICS + '">Topics</option>',
            '</select>',
            '<a id="sgheViewAllTopics" href="/CommonsSunGardHE/pages/categories/" target="topics">View all topics</a>',
            '</div>',
            '</div></div>'
        ].join('\n');

        jQuery('#sb-2>.wrapper').prepend(sgheSearch);
        var mainSearch = jQuery('#main-search input[type=text]');

        // to initialize, copy from central search into custom search
        jQuery('#sgheViewAllTopics').attr('href', communityURL + 'pages/categories/');
        jQuery('#sgheSearchText').val( mainSearch.val() );
        jQuery('#sgheSearchIn').val( function() {
            var searchChecked = jQuery('#main-search input[type=radio]:checked')
            var contentTopicProfile = searchChecked.eq(0).val();
            var communityGlobal = searchChecked.eq(1).val();
            var searchIn = LOCAL; // local community
            if (contentTopicProfile == EDU1_TOPICS) {
                searchIn = TOPICS;
            } else if (contentTopicProfile == EDU1_PROFILES) {
                searchIn = PROFILES;
            } else if (communityGlobal == EDU1_GLOBAL) {
                searchIn = GLOBAL;
            }
            return searchIn;
        });

        var toggleViewAllTopics = function() {
            if (TOPICS == jQuery('#sgheSearchIn').val()) {
	            jQuery('#sgheViewAllTopics').css('display','block');
            } else {
	            jQuery('#sgheViewAllTopics').css('display','none');
            }
        };

        // on any change, copy from sghe to central
        var copySearch = function() {
            mainSearch.val( jQuery('#sgheSearchText').val() );
            var searchIn = jQuery('#sgheSearchIn').val();
            var contentTopicProfile = 0;
            var communityGlobal = 0;
            switch ( searchIn ) {
            case GLOBAL:
                communityGlobal = EDU1_GLOBAL;
                break;
            case TOPICS:
                contentTopicProfile = EDU1_TOPICS;
                break;
            case PROFILES:
                contentTopicProfile = EDU1_PROFILES;
                break;
            }
            jQuery('#main-search input[name=ctl00$centerSearchCtrl$rblstSearchIn][value='+contentTopicProfile+']').attr( 'checked', true );
            jQuery('#main-search input[name=ctl00$centerSearchCtrl$rblGroups][value='+communityGlobal+']').attr( 'checked', true );

            toggleViewAllTopics();
        };
        var submitSearch = function() {
            copySearch();
            $('#main-search [alt=Search]').click();
            return false;
        };
        var keypressSubmitSearch = function(event) {
            if (event.keyCode == 13) {
	            submitSearch();
                return false;
            }
        }

        jQuery('#sgheSearchText').keypress( keypressSubmitSearch );
        jQuery('#sgheSearchIn').keypress( keypressSubmitSearch );
        jQuery('#sgheSearchImage').click( submitSearch );

        jQuery('#sgheSearchIn').change( copySearch );
        toggleViewAllTopics();

        var reorderModules = function() {
            function selectTitle(arg) {
                return '#sb-2 div h2.title:contains(' + arg + ')';
            }

            function moduleContaining( jqObj ) {
                return jqObj.parents('#sb-2 div.section').first();
            }

            function module(val) {
                var obj = $( '#sb-2 ' + val );
                return obj.is('.section') ?
                    obj :
                    moduleContaining(obj);
            }

            var removeModule = [
                '#sb-2 div.custom-content img[src*=house.png]', // Current Community
                'div.navigate-back',
            ];

            $.each(removeModule, function(idx,val) {
                var mod = module( val );
                sghe.log('removing: ', val, mod);
                mod.remove();
            });

            //!!What about special announcements, like SunGard Summit or Speaker Request form?
            //!!order by # title
            var moduleOrder = [
                '#sghesearchmodule',//* Search
                'div.share-with-us', //(2) Share with Us/Start a Discusssion
                '#sb-user-notifications',//"(3) User Notification, displays only new inbox"
                // selectTitle('Find It Fast'),//(4) Find It Fast
                // '#sb-group-links',//"(5) Links  (Bookmarks), displays only if content"
                // selectTitle('Workspace'),//(6) Community Workspace
                // '#sb-group-tags',//"popular tags: (7) Top Custom Tags, displays only if content"
                // 'div.tags',// for the general tags cloud - not specified by Dale/Bill
                // '#sb-group-poll',//"(8) Poll,displays only if content"
                // '#sb-group-news',//"(9) News,    displays only if content"
                // '#sb-group-events',//"(10) Event calendar,displays only if content"
                // '#sb-recent-comments',//? Recent Comments
                // '#sb-group-archives',//? Blogs Archive Calendar
                // selectTitle('Committee Members'),//? Committee members
                // selectTitle('Featured Blogs'),
                // '#sb-group-feeds',//(11) RSS  (Feeds)
                // '#sb-highest-rated-users',//? Highest Rated Authors
                // '#sb-most-discussed-users',//? Most Discussed Authors
                // '#sb-group-statistics',//? Statistics
                // selectTitle('Follow Us'),//" Follow Us,on main community only - last"
            ];

            var reversed = moduleOrder.slice(0).reverse();
            var dest = $('#sb-2>.wrapper');
            $.each( reversed, function(idx,val) {
                var text = module( val ).prependTo( dest ).text();
                sghe.log( 'moved ', idx, val, text || 'not found' );
            });

            // // insert custom modules with specific numbers
            // var objs = $('#sb-2 div.section.custom-content h2.title').toArray();
            // $.each(objs, function(idx,ele) {
            //     var h2 = $(ele);
            //     var match = h2.text().match( /^(\d+) (.*)/ );
            //     if ( match  ) {
            //         var index = Math.max( match[1], 3 );
            //         //console.log( 'moving number ', index, idx, h2.text() );
            //         index = Math.max( index, 3 );
            //         h2.text(match[2] || match[0]); // prefer just the text
            //         var dest = $('#sb-2 .wrapper>.section:nth-child(' + index + ')');
            // 
            //         //console.log( 'moving number ', index, idx, h2.text(), dest.text() );
            //         var mod = moduleContaining( h2 );
            //         mod.insertBefore( dest );
            //     }
            // });
            // sghe.log('move and reorder sidebar modules');
        }
        reorderModules();

        // show/hide modules
        var uiiconspan = $('<span>').addClass("ui-icon ui-icon-triangle-1-s");
        function storage(element, value) {
            var name = 'setting-' + ($(element).text() || $(element).parent().text());
            sghe.log( 'storage: ', name, element, value );
            if (value === undefined) {
                return sghe.localStorage.getItem(name);
            } else {
                sghe.localStorage.removeItem(name);
                sghe.localStorage.setItem(name, value);
            }
        }
        $('#sb-2 .section h2.title').prepend(uiiconspan).click( function (evt) {
            var arrow = $('.ui-icon',this);
            arrow.toggleClass('ui-icon-triangle-1-s ui-icon-triangle-1-e');
            var visible = arrow.is('.ui-icon-triangle-1-s'); //south = visible
            $(this).next().slideToggle('fast');
            storage(evt.target, visible);
        }).each(function(idx,element) {
            var val = storage(element);
            sghe.log( idx, 'loading:', element, val);
            if (val == 'false') { $(element).click(); }
        });

        // hide lines and restructure Headline result on chronological listing
        $('#ctl00_phMain_ctrlListPostsByPeriod_grdPosts_ctl01 .date').parent().css('border-bottom','0px');
        $('#ctl00_phMain_ctrlListPostsByPeriod_grdPosts_ctl01 .date').each(
            function() {
                $(this).appendTo(
                    $(this).prev('.author')
                )
            }
        );

        function replaceButtons() {
            // Currently dependent on the edu1world filenames, could change to depend on alt text.
            buttons = [
                'http://www.edu1world.org/CustomButtonImages/cb_img_0b2a08e88345d4b2df550223540cdb50.png', //Start a Discussion
                'http://www.edu1world.org/CustomButtonImages/cb_img_dbd0eb0f04250b87e5f14fc6136a29d5.png',//Send Invitation(s)
                'http://www.edu1world.org/CustomButtonImages/cb_img_9a45d90a8e2d3c2dc5ba1a47e58c6d3c.png',//Cancel
                'http://www.edu1world.org/CustomButtonImages/cb_img_05c784ea3c6e144bc6acf1e0c9f2f343.png',//Save
                'http://www.edu1world.org/App_Themes/BlogSunGard/images/buttons/wfsyn-button-navigate-back.png',//guess.  Navigate back
                'http://www.edu1world.org/CustomButtonImages/cb_img_5bd4d1f0e4d923b9a76ee69190cdfd47.png',//Vote
                'http://www.edu1world.org/CustomButtonImages/cb_img_52cfbd0f8cc2a3244361ce08c435350d.png',//Upload File
                'http://www.edu1world.org/CustomButtonImages/cb_img_2f895916b39687b76a460038087e955a.png',//Back
                'http://www.edu1world.org/App_Themes_Main/images/icons/silk/add.png', // icon: plus-in-a-circle
                'http://www.edu1world.org/CustomButtonImages/cb_img_93f38a136ae33ee8b4da7b7ae6c7800b.png', //Save
                'http://www.edu1world.org/CustomButtonImages/cb_img_d6858429f76ca67e9f17e80607d16e8d.png', //Save as a Draft
                'http://www.edu1world.org/CustomButtonImages/cb_img_f111d53aff5ad50935553b25aa252a64.png', // GENERATE SUMMARY (all caps!)
                'http://www.edu1world.org/CustomButtonImages/cb_img_9be5fb0ad1faa97a8c2c5f72e62717a4.png' //Send

            ];
            var start = new Date().getTime();
            $.each( buttons, function(idx,value) {
                //sghe.log( idx + ":" + value + ' img[src*=' + value + ']' );

                try {
                    var found = $('[src*=' + value + ']');
                    found.length && sghe.log( "Found: " + value + ': ' + found.length );
                    found.attr('src','http://commons.sungardhe.com/static/images/buttons/'+value.split('/').pop());
                } catch (e) {
                    sghe.log( "Failed to replaceButton: " + value );
                }
            });
            var end = new Date().getTime();
            sghe.log( "Buttons took " + (end - start) + " milliseconds.") ;
        }
        replaceButtons();
        // for the GENERATE SUMMARY button
        $('#phMain_addeditPostControl_phAdvanced').live('DOMNodeInserted', function(event) {
            replaceButtons();
        });

        // wrap in sghe-site-border
        // this may cause problems with Javascript that executes later in IE
        // but it is very visual, so we'd like it to happen early.
        // but also for IE, if we modify the DOM before load is complete, we get an operation aborted
        // choices choices...  Is it worth special-casing for non-IE browsers?
        function stripScripts(jq){
            jq.find('script').each( function() {
                if ($.contains(document.documentElement, this )) {
                    var script = jQuery( this );
                    var type = script.attr('type');
                    if (!type || type.toLowerCase() === 'text/javascript') {
                        script.remove();
                    }}});
        }

        function sgheSiteBorder() {
            var page = $('#site-wrap').children().not('#top-nav');
            stripScripts(page);
            page.wrapAll('<div id="sghe-site-border">');
        }
        if ( $.browser.msie ) {
            jQuery(sgheSiteBorder); // can't modify DOM structure this way before load is complete on IE7 or less.
            // also may cause problems for Javascript that executes later if done early...
            //$('.layout-scs #content').css('width','570px'); /* IE pushes right column down with width=586px, other browsers need 586px for balance */
            //$('#sgheSearch input.image-button').css('margin-top','-7px');
        } else {
            sgheSiteBorder(); // happen early for non-IE browsers.
        }

        sghe.coverdone = true;
        $('.sghe-cover').hide();

	// move footer into middle section
	//$('#footer').append($('#middle'))

        function fixSignup() {
            // signup link->commons web registration page (most communities do it in private/premium landing page)
            jQuery('li.register > a').attr('href','/submitform/SunGardHECommonsInvitation/');
        }
    
        function chooseLoggedin() {
            var loggedin = username ? true : false;
            jQuery('#loggedin').toggle(loggedin);
            jQuery('#notloggedin').toggle(!loggedin);
        }
    
        function fixLoginCopy() {
            // on premium/private landing pages 
            jQuery('#logincopy').attr('href', jQuery('li.login > a').attr('href'));
        };
    
        fixSignup();
        chooseLoggedin();
        fixLoginCopy();
        
        // add separators for wiki breadcrumb
        jQuery('.bc-nav a:not(:first)').before('<span style="color:#369"> | </span>')

        // add zebra-striping for entry posts
        jQuery('.post').filter(':odd').addClass('odd');

        // highlight ' new' comment count
        jQuery('.entry-header a:contains( new)').addClass('sghenewcomments');

        function highlightUnApprovedEntries(selector){
            $(selector).each( function() {
                var $entry = $(this);
                $entry.find('.entry-footer input:checkbox').each( function() {
                    var $checkbox = $(this);
                    var $label = $checkbox.next();
                    if ($label.html() == "Approved") {
                        var approved = Boolean( $checkbox.attr('checked') );
                        $entry.toggleClass( 'sgheunapproved', !approved );
                    }
                });
            });
        }
        
        // highlight discussions and comments
        highlightUnApprovedEntries('.section.posts .entry, .section.comments .entry');  

        // hide the sidebar and grow the content for adding/editing wiki pages
        //!! should we do this for posts and for viewing wiki pages?
        if ( document.URL.match( /\/wiki\/document\/(add)|(edit)\// )) {
            $('#sb-1 .wrapper').hide();
            $('.layout-cs #content').css('width','100%');
        }

        ////////// enhance wiki folders
        function toggleFolder() {
            var $parent = $(this.parentNode);
            $('.ui-icon',$parent).first().toggleClass('ui-icon-triangle-1-s ui-icon-triangle-1-e');
            $('div.sghe-wiki-folder-children',$parent).first().slideToggle('fast');
            return false;
        }

        function genLinks( cssClass, data ) {
            var links$ = jQuery(cssClass, data);
            var linksChildDiv = jQuery('<div>');
            links$.each( function(idx,obj) { linksChildDiv.prepend( jQuery('<div>').append( obj ));});
            return [ links$.size(), linksChildDiv ];
        }

        function callbackInsert( parent, data ) {
            var folders = genLinks( '.grid-wiki a.folder-link', data );
            enhanceFolders( folders[1].find( 'a.folder-link' ));
            var pages = genLinks( '.grid-wiki a.file-link', data );

            var arrowSpan = $('<a href=""><span class="ui-icon ui-icon-triangle-1-e" style="float:left"></span></a>');
            var summary = $("<a href='' class='sgheExpand'><span style='display:block;clear:both;margin-left:16px'>&nbsp;subfolders: " + folders[0] + " pages: " + pages[0] + "</span></a>");
            arrowSpan.click( toggleFolder );
            summary.click( toggleFolder );

            sghe.log( parent + " summary: " + summary );
            var children = jQuery('<div class="sghe-wiki-folder-children" style="margin-left:16px;display:none">').append( folders[1] ).append( pages[1] );

            var $parent = jQuery( parent );
            $parent.before( arrowSpan ).after( summary );
            summary.after( children );
        }

        function enhanceFolders(obj$) {
            obj$.each( function() {
                var parent = this;
                function callback( data, textStatus, httprequest ) {
                    callbackInsert( parent, data );
                }
                jQuery.get(this.href, callback );
            });
        }

        if ( !document.location.href.match( /\/CommonsInternational\// )) {
            enhanceFolders( jQuery('div.wiki a.folder-link') );

            if ( $('.wiki .folder-link').size() > 0 ) {
                function toggleAllFolders(show) {
                    // click all of the right-facing arrows (-e) to expand, all down facing (-s) to collapse
                    var toChange = '.ui-icon-triangle-1-' + (show?'e':'s');
                    // find the top-level '.sgheExpand' links, go back to the arrowSpan's parent, and click it
                    $('td>a.sgheExpand').prev().prev().find(toChange).parent().click();
                    $('.sgheExpandAll').toggle(!show);
                    $('.sgheCollapseAll').toggle(show);
                }

                $(".wiki #ctl00_phMain_rgrdAllSpaces").before(
                    $('<a href="" class="sgheExpandAll">Expand all folders</a><a href="" class="sgheCollapseAll" style="display:none">Collapse all folders</a>').click( function() {
                        var show = this.className === 'sgheExpandAll';
                        toggleAllFolders( show );
                        return false;
                    }));
            }
        }

        ////////// Fix parent folder text
        $('#phMain_btnParentDirectory').text() == 'fm_parent_directory' && $('#phMain_btnParentDirectory').text('Parent Folder');
        // hide the default root folder name 'Documents'
        $('#phMain_btnParentDirectory').length == 0 && $('.wf-title h2.title').text() == 'Documents' && $('.wf-title h2.title').hide();
    
        ////////// remove doc aliases that exactly match their doc title link
        var count =$('.row td a').parent().contents().filter(
            // do this by finding text nodes that, with white space removed, exactly match
            // the closest preceding hypertext link
            function() {
	            return (
		            this.nodeType == 3
		                && this.nodeValue.trim()
		                && this.nodeValue.trim() == $(this).prev('a').text()
                );
	        }).remove().size();
        sghe.log( "Hid aliases: " + count );

        ////////// move Add Invitation link after table
        $('#ctl00_phMain_btnAddInvitation').parent().next('table').after($('#ctl00_phMain_btnAddInvitation').parent())

        ////////// duplicate RSS feeds
        function addAtomFeed(num, item) {
            var replacements = {
                '14':'12',
                '24':'x',//'22',
                '34':'x',//'32',
                '84':'x',//'82',
                '94':'x',//'92',
                '4' :'x'//'2'
            };
            try {
                var obj = jQuery(item);
                var link = obj.attr( 'href' );
                var match = link.match( /type=(\d+)/ );
                var linkId = match ? match[1]:null;
                if ( replacements[linkId]  ) {
                    var newObj = obj.clone();
                    var title = "Full article feed";
                    newObj.attr( "href", link.replace( /type=(\d+)/, "type=" + replacements[linkId] ))
                        .find("img").attr("src", "http://commons.sungardhe.com/static/images/feed-icon-green-12.png" )
                        .attr("title", title );
                    obj.before( newObj ).before( ' ' );
                    if (replacements[linkId] == 'x') { newObj.attr( "style", "visibility:hidden" ); }
                }
                title = "Article summary feed";
                obj.attr( "title", title).before( newObj ).before( ' ' ).find('img').attr('alt',title);
            }
            catch (err)
            {
                //var vDebug = "";
                //for (var prop in err)
                //{
                //   vDebug += "property: "+ prop+ " value: ["+ err[prop]+ "]\\n"; "Javascript escape newline"
                //}
                //vDebug += "toString(): " + " value: [" + err.toString() + "]";
                //sghe.log( vDebug );
            }
        }
        jQuery( "#sb-group-feeds li a:first-child" ).each(addAtomFeed);
        jQuery( "#sb-group-feeds li input[title=Add to My Home]").attr("title","Add to My Workplace");

        // right-align statistics numbers
        $('.statistics p br').css('clear','both');

        jQuery('a.sgheuser').each( function(i,el) { el.href=el.href.replace('{{username}}', sghe.username);} );

        var loginHref = jQuery('li.login a').attr('href');
        if ( loginHref ) {
            jQuery('a[href=../../../pages/login/]').attr('href', loginHref);
        }
        
        function resizeWiki(){
            var wikiId="#ctl00_phMain_ctrlWikiDocumentControl__editorDoc_editorCenter";
            var min = 150;
            if (!jQuery) { sghe.log( 'jQuery not defined' ); return; }
            var height = Math.max(min, jQuery(window).height() - 325 );
            var delta = 200;
            jQuery(wikiId).css("height",height+'px').closest('div').css('height',(height+delta)+'px');
            sghe.log( "resized wiki editor" );// + jQuery(iframename).size() + jQuery(iframename).css('height') );

        }
        resizeWiki();
        window.setTimeout( resizeWiki, 3000 );

        // adjust broken structure
        if ( document.location.href.match( /kbsandbox/ ) || !$.browser.msie ) {
            $(".post .post").each( function( idx, ele ) {
                var x = $(ele);
                x.parents('.post').parent().append(x);
            });
            var sidebar = $('.post #sb-2');
            sghe.log( 'looking at sidebar:' + sidebar.length, sidebar );
            if (sidebar.length) {
                sghe.log( 'stripped' );
                stripScripts(sidebar);
                sghe.log( 'inserting' );
                sidebar.insertAfter('#content');
                sghe.log( 'inserted' );
            }
        }
        
        // tabbed panels for partner information
        if ( document.getElementById( 'TabbedPanels' )) {
            sghe.addCss = function(url) {
                var newElement = document.createElement('link');
                newElement.setAttribute('rel','stylesheet');
                newElement.setAttribute('type','text/css');
                newElement.setAttribute('media','screen');
                newElement.setAttribute('href', url);
                document.getElementsByTagName('head')[0].appendChild(newElement);
            }

            sghe.addScript = function(url,onload) {
                var newElement = document.createElement('script');
                newElement.setAttribute('type','text/javascript');
                newElement.setAttribute('src',url);
                //if ( onload ) { newElement.setAttribute( 'onload', onload ) };
                document.getElementById('TabbedPanels').appendChild(newElement);
            }

            // hide rate control:
            jQuery(".vote-control").hide();

            function makeTabbed() {
                sghe.log( "makeTabbed");
                var TabbedPanels1 = new Spry.Widget.TabbedPanels("TabbedPanels");
                var TabbedPanels2 = new Spry.Widget.TabbedPanels("ProductTabs");
                sghe.log( "done makeTabbed");
            }
            function makeCollapsible() {
                sghe.log( "makeCollapsible");
                $('.CollapsiblePanel').each(
                    function() {
                        sghe.log( this.id );
                        new Spry.Widget.CollapsiblePanel( this.id );
                    });
                sghe.log( "done makeCollapsible");
            }

            sghe.log( "adding css" );
            sghe.addCss('http://commons.sungardhe.com/static/tabbedpanels/css/SpryTabbedPanels.css');
            sghe.addCss('http://commons.sungardhe.com/static/tabbedpanels/css/SpryCollapsiblePanel.css')
            sghe.addCss('http://commons.sungardhe.com/static/tabbedpanels/css/company-profile.css');

            sghe.log( "adding script" );
            // refactor this to use jQuery.getScript(..., onsuccess)
            sghe.addScript("http://commons.sungardhe.com/static/tabbedpanels/js/SpryTabbedPanels.js", 'makeTabbed()');
            sghe.addScript("http://commons.sungardhe.com/static/tabbedpanels/js/SpryCollapsiblePanel.js", 'makeCollapsible()' );
            sghe.log( "done with partners");

            /////printstacktrace
            
            // Domain Public by Eric Wendelin http://eriwen.com/ (2008)
            //                  Luke Smith http://lucassmith.name/ (2008)
            //                  Loic Dachary <loic@dachary.org> (2008)
            //                  Johan Euphrosine <proppy@aminche.com> (2008)
            //                  Øyvind Sean Kinsey http://kinsey.no/blog (2010)
            //
            // Information and discussions
            // http://jspoker.pokersource.info/skin/test-printstacktrace.html
            // http://eriwen.com/javascript/js-stack-trace/
            // http://eriwen.com/javascript/stacktrace-update/
            // http://pastie.org/253058
            //
            // guessFunctionNameFromLines comes from firebug
            //
            // Software License Agreement (BSD License)
            //
            // Copyright (c) 2007, Parakey Inc.
            // All rights reserved.
            //
            // Redistribution and use of this software in source and binary forms, with or without modification,
            // are permitted provided that the following conditions are met:
            //
            // * Redistributions of source code must retain the above
            //   copyright notice, this list of conditions and the
            //   following disclaimer.
            //
            // * Redistributions in binary form must reproduce the above
            //   copyright notice, this list of conditions and the
            //   following disclaimer in the documentation and/or other
            //   materials provided with the distribution.
            //
            // * Neither the name of Parakey Inc. nor the names of its
            //   contributors may be used to endorse or promote products
            //   derived from this software without specific prior
            //   written permission of Parakey Inc.
            //
            // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
            // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
            // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
            // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
            // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
            // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
            // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
            // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
            
            /**
             * Main function giving a function stack trace with a forced or passed in Error 
             *
             * @cfg {Error} e The error to create a stacktrace from (optional)
             * @cfg {Boolean} guess If we should try to resolve the names of anonymous functions
             * @return {Array} of Strings with functions, lines, files, and arguments where possible 
             */
            function printStackTrace(options) {
                var ex = (options && options.e) ? options.e : null;
                var guess = options ? !!options.guess : true;
                
                var p = new printStackTrace.implementation();
                var result = p.run(ex);
                return (guess) ? p.guessFunctions(result) : result;
            }
            
            printStackTrace.implementation = function() {};
            
            printStackTrace.implementation.prototype = {
                run: function(ex) {
                    // Use either the stored mode, or resolve it
                    var mode = this._mode || this.mode();
                    if (mode === 'other') {
                        return this.other(arguments.callee);
                    } else {
                        ex = ex ||
                            (function() {
                                try {
                                    var _err = __undef__ << 1;
                                } catch (e) {
                                    return e;
                                }
                            })();
                        return this[mode](ex);
                    }
                },
                
                /**
                 * @return {String} mode of operation for the environment in question.
                 */
                mode: function() {
                    try {
                        var _err = __undef__ << 1;
                    } catch (e) {
                        if (e['arguments']) {
                            return (this._mode = 'chrome');
                        } else if (window.opera && e.stacktrace) {
                            return (this._mode = 'opera10');
                        } else if (e.stack) {
                            return (this._mode = 'firefox');
                        } else if (window.opera && !('stacktrace' in e)) { //Opera 9-
                            return (this._mode = 'opera');
                        }
                    }
                    return (this._mode = 'other');
                },
                
                /**
                 * Given a context, function name, and callback function, overwrite it so that it calls
                 * printStackTrace() first with a callback and then runs the rest of the body.
                 * 
                 * @param {Object} context of execution (e.g. window)
                 * @param {String} functionName to instrument
                 * @param {Function} function to call with a stack trace on invocation
                 */
                instrumentFunction: function(context, functionName, callback) {
                    context = context || window;
                    context['_old' + functionName] = context[functionName];
                    context[functionName] = function() { 
                        callback.call(this, printStackTrace());
                        return context['_old' + functionName].apply(this, arguments);
                    };
                    context[functionName]._instrumented = true;
                },
                
                /**
                 * Given a context and function name of a function that has been
                 * instrumented, revert the function to it's original (non-instrumented)
                 * state.
                 *
                 * @param {Object} context of execution (e.g. window)
                 * @param {String} functionName to de-instrument
                 */
                deinstrumentFunction: function(context, functionName) {
                    if (context[functionName].constructor === Function &&
                        context[functionName]._instrumented &&
                        context['_old' + functionName].constructor === Function) {
                        context[functionName] = context['_old' + functionName];
                    }
                },
                
                /**
                 * Given an Error object, return a formatted Array based on Chrome's stack string.
                 * 
                 * @param e - Error object to inspect
                 * @return Array<String> of function calls, files and line numbers
                 */
                chrome: function(e) {
                    return e.stack.replace(/^[^\\n]*\\n/, '').replace(/^[^\\n]*\\n/, '').replace(/^[^\(]+?[\\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@').split('\\n');
                },
                
                /**
                 * Given an Error object, return a formatted Array based on Firefox's stack string.
                 * 
                 * @param e - Error object to inspect
                 * @return Array<String> of function calls, files and line numbers
                 */
                firefox: function(e) {
                    return e.stack.replace(/^[^\\n]*\\n/, '').replace(/(?:\\n@:0)?\s+$/m, '').replace(/^\(/gm, '{anonymous}(').split('\\n');
                },
                
                /**
                 * Given an Error object, return a formatted Array based on Opera 10's stacktrace string.
                 * 
                 * @param e - Error object to inspect
                 * @return Array<String> of function calls, files and line numbers
                 */
                opera10: function(e) {
                    var stack = e.stacktrace;
                    var lines = stack.split('\\n'), ANON = '{anonymous}',
                    lineRE = /.*line (\d+), column (\d+) in ((<anonymous function\:?\s*(\S+))|([^\(]+)\([^\)]*\))(?: in )?(.*)\s*$/i, i, j, len;
                    for (i = 2, j = 0, len = lines.length; i < len - 2; i++) {
                        if (lineRE.test(lines[i])) {
                            var location = RegExp.$6 + ':' + RegExp.$1 + ':' + RegExp.$2;
                            var fnName = RegExp.$3;
                            fnName = fnName.replace(/<anonymous function\s?(\S+)?>/g, ANON);
                            lines[j++] = fnName + '@' + location;
                        }
                    }
                    
                    lines.splice(j, lines.length - j);
                    return lines;
                },
                
                // Opera 7.x-9.x only!
                opera: function(e) {
                    var lines = e.message.split('\\n'), ANON = '{anonymous}', 
                    lineRE = /Line\s+(\d+).*script\s+(http\S+)(?:.*in\s+function\s+(\S+))?/i, 
                    i, j, len;
                    
                    for (i = 4, j = 0, len = lines.length; i < len; i += 2) {
                        //TODO: RegExp.exec() would probably be cleaner here
                        if (lineRE.test(lines[i])) {
                            lines[j++] = (RegExp.$3 ? RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 : ANON + '()@' + RegExp.$2 + ':' + RegExp.$1) + ' -- ' + lines[i + 1].replace(/^\s+/, '');
                        }
                    }
                    
                    lines.splice(j, lines.length - j);
                    return lines;
                },
                
                // Safari, IE, and others
                other: function(curr) {
                    var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i,
                    stack = [], j = 0, fn, args;
                    
                    var maxStackSize = 10;
                    while (curr && stack.length < maxStackSize) {
                        fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
                        args = Array.prototype.slice.call(curr['arguments']);
                        stack[j++] = fn + '(' + this.stringifyArguments(args) + ')';
                        curr = curr.caller;
                    }
                    return stack;
                },
                
                /**
                 * Given arguments array as a String, subsituting type names for non-string types.
                 *
                 * @param {Arguments} object
                 * @return {Array} of Strings with stringified arguments
                 */
                stringifyArguments: function(args) {
                    for (var i = 0; i < args.length; ++i) {
                        var arg = args[i];
                        if (arg === undefined) {
                            args[i] = 'undefined';
                        } else if (arg === null) {
                            args[i] = 'null';
                        } else if (arg.constructor) {
                            if (arg.constructor === Array) {
                                if (arg.length < 3) {
                                    args[i] = '[' + this.stringifyArguments(arg) + ']';
                                } else {
                                    args[i] = '[' + this.stringifyArguments(Array.prototype.slice.call(arg, 0, 1)) + '...' + this.stringifyArguments(Array.prototype.slice.call(arg, -1)) + ']';
                                }
                            } else if (arg.constructor === Object) {
                                args[i] = '#object';
                            } else if (arg.constructor === Function) {
                                args[i] = '#function';
                            } else if (arg.constructor === String) {
                                args[i] = '"' + arg + '"';
                            }
                        }
                    }
                    return args.join(',');
                },
                
                sourceCache: {},
                
                /**
                 * @return the text from a given URL.
                 */
                ajax: function(url) {
                    var req = this.createXMLHTTPObject();
                    if (!req) {
                        return;
                    }
                    req.open('GET', url, false);
                    req.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
                    req.send('');
                    return req.responseText;
                },
                
                /**
                 * Try XHR methods in order and store XHR factory.
                 *
                 * @return <Function> XHR function or equivalent
                 */
                createXMLHTTPObject: function() {
                    var xmlhttp, XMLHttpFactories = [
                        function() {
                            return new XMLHttpRequest();
                        }, function() {
                            return new ActiveXObject('Msxml2.XMLHTTP');
                        }, function() {
                            return new ActiveXObject('Msxml3.XMLHTTP');
                        }, function() {
                            return new ActiveXObject('Microsoft.XMLHTTP');
                        }
                    ];
                    for (var i = 0; i < XMLHttpFactories.length; i++) {
                        try {
                            xmlhttp = XMLHttpFactories[i]();
                            // Use memoization to cache the factory
                            this.createXMLHTTPObject = XMLHttpFactories[i];
                            return xmlhttp;
                        } catch (e) {}
                    }
                },
                
                /**
                 * Given a URL, check if it is in the same domain (so we can get the source
                 * via Ajax).
                 *
                 * @param url <String> source url
                 * @return False if we need a cross-domain request
                 */
                isSameDomain: function(url) {
                    return url.indexOf(location.hostname) !== -1;
                },
                
                /**
                 * Get source code from given URL if in the same domain.
                 *
                 * @param url <String> JS source URL
                 * @return <String> Source code
                 */
                getSource: function(url) {
                    if (!(url in this.sourceCache)) {
                        this.sourceCache[url] = this.ajax(url).split('\\n');
                    }
                    return this.sourceCache[url];
                },
                
                guessFunctions: function(stack) {
                    for (var i = 0; i < stack.length; ++i) {
                        var reStack = /\{anonymous\}\(.*\)@(\w+:\/\/([\-\w\.]+)+(:\d+)?[^:]+):(\d+):?(\d+)?/;
                        var frame = stack[i], m = reStack.exec(frame);
                        if (m) {
                            var file = m[1], lineno = m[4]; //m[7] is character position in Chrome
                            if (file && this.isSameDomain(file) && lineno) {
                                var functionName = this.guessFunctionName(file, lineno);
                                stack[i] = frame.replace('{anonymous}', functionName);
                            }
                        }
                    }
                    return stack;
                },
                
                guessFunctionName: function(url, lineNo) {
                    try {
                        return this.guessFunctionNameFromLines(lineNo, this.getSource(url));
                    } catch (e) {
                        return 'getSource failed with url: ' + url + ', exception: ' + e.toString();
                    }
                },
                
                guessFunctionNameFromLines: function(lineNo, source) {
                    var reFunctionArgNames = /function ([^(]*)\(([^)]*)\)/;
                    var reGuessFunction = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(function|eval|new Function)/;
                    // Walk backwards from the first line in the function until we find the line which
                    // matches the pattern above, which is the function definition
                    var line = "", maxLines = 10;
                    for (var i = 0; i < maxLines; ++i) {
                        line = source[lineNo - i] + line;
                        if (line !== undefined) {
                            var m = reGuessFunction.exec(line);
                            if (m && m[1]) {
                                return m[1];
                            } else {
                                m = reFunctionArgNames.exec(line);
                                if (m && m[1]) {
                                    return m[1];
                                }
                            }
                        }
                    }
                    return '(?)';
                }
            };
            
            /////end printstacktrace
            sghe.printStackTrace = printStackTrace;
            
            var doinit_attempts = 0;
            var lastTrace = '';
            sghe.doinit = function() {
                sghe.log( "doinit beginning");
                try {
                    makeTabbed();
                    makeCollapsible();
                } catch ( err ) {
                    if ( err.arguments=='Spry'
                         || (err.description && err.description.match(/Spry/))
                         || (err.message && err.message.match(/Spry/))
                       ) { // instanceof TypeError or ReferenceError
                        window.setTimeout( "sghe.doinit()", 100 );
                        sghe.log( "retrying for Spry load" );
                    } else {
                        var trace = sghe.printStackTrace({e:err});
                        if (trace == lastTrace) { sghe.log('same exception'); }
                        else {lastTrace = trace; sghe.log( trace );}
                        if (doinit_attempts++ > 100) { sghe.log( "failed for 10 seconds" ); throw err; }
                        for ( v in err ) { sghe.log( '  data: ' + v + ':' + err[v] ); }
                    }
                }
            }
            
            sghe.doinit();
        }
    });

    // localStorage/sessionStorage polyfill https://gist.github.com/350433
    var Storage = function (type) {
        function createCookie(name, value, days) {
            var date, expires;

            if (days) {
                date = new Date();
                date.setTime(date.getTime()+(days*24*60*60*1000));
                expires = "; expires="+date.toGMTString();
            } else {
                expires = "";
            }
            document.cookie = name+"="+value+expires+"; path=/";
        }

        function readCookie(name) {
            var nameEQ = name + "=",
            ca = document.cookie.split(';'),
            i, c;

            for (i=0; i < ca.length; i++) {
                c = ca[i];
                while (c.charAt(0)==' ') {
                    c = c.substring(1,c.length);
                }

                if (c.indexOf(nameEQ) == 0) {
                    return c.substring(nameEQ.length,c.length);
                }
            }
            return null;
        }

        function setData(data) {
            data = JSON.stringify(data);
            if (type == 'session') {
                window.name = data;
            } else {
                createCookie('localStorage', data, 365);
            }
        }

        function clearData() {
            if (type == 'session') {
                window.name = '';
            } else {
                createCookie('localStorage', '', 365);
            }
        }

        function getData() {
            var data = type == 'session' ? window.name : readCookie('localStorage');
            return data ? JSON.parse(data) : {};
        }


        // initialise if there's already data
        var data = getData();

        return {
            length: 0,
            clear: function () {
                data = {};
                this.length = 0;
                clearData();
            },
            getItem: function (key) {
                return data[key] === undefined ? null : data[key];
            },
            key: function (i) {
                // not perfect, but works
                var ctr = 0;
                for (var k in data) {
                    if (ctr == i) return k;
                    else ctr++;
                }
                return null;
            },
            removeItem: function (key) {
                delete data[key];
                this.length--;
                setData(data);
            },
            setItem: function (key, value) {
                data[key] = value+''; // forces the value to a string
                this.length++;
                setData(data);
            }
        };
    };

    if (typeof window.localStorage == 'undefined') window.localStorage = new Storage('local');
    if (typeof window.sessionStorage == 'undefined') window.sessionStorage = new Storage('session');

    sghe.localStorage = window.localStorage || new Storage('local'); /* Firefox dom.storage.enabled makes window.localStorage null even after assignment */

    return sghe;
})(sghe || {});

var _gaq = _gaq || [];
_gaq.push(['_sghega._setAccount', 'UA-15501404-1']);
_gaq.push(['_sghega._setDomainName', '.edu1world.org']);
_gaq.push(['_sghega._trackPageview']);

function addCover() {
    var cover = $('.aspNetHidden');
    if (!cover.length) {
        setTimeout(addCover, 10);
    } else {
        if ( sghe.coverRetries === undefined ) {
            sghe.coverRetries = 1000;
        }
        if (!sghe.coverdone ) {
            try {
sghe.log('attempting to add cover', sghe.coverRetries);
                $(cover).addClass('sghe-cover').attr('style','position:absolute; top:0; left:0; width:100%; height:100%; z-index:999999; background:white;');
                setTimeout(function() {$('.sghe-cover').hide();}, 5000); // hide cover after 5 seconds

sghe.log('completed attempting to add cover', sghe.coverRetries);
            } catch ( err ) {
sghe.log('failed attempting to add cover', sghe.coverRetries);
                if ( sghe.coverRetries-- ) {
                    setTimeout(addCover, 10);
                } else {
                    sghe.log( 'Failed to add sghe-cover', err );
                }
            }
        }
    }
}
addCover();
        
