
instGraph = new Graph();

ui = {
    currPalette : null,
    currCanvas: null,
    contextHeader: null,
    paletteContainer : null,
    paletteActions: null,
    paletteOptions: null,
    paletteDisplay: null,   
    canvasContainer : null,
    canvasActions: null,
    canvasOptions: null,
    canvasDisplay: null,
    paletteSpinner : null,
    canvasSpinner: null,
    paletteConfirmedGraph : new Graph(),
    error: false, 
    
    //this should be removed in favor of attaching the Subject to the context itself
    //will require refactoring a lot of the references :(
    currContextSubject: null, // the current context Subject (or null, if creating) being worked on
    
    
    useContext: function (cntxt, replace, cgURI) {
        //TODO: this replace business is either borked or serves no purpose whatsoever.
        if(replace) {
            if(ui.currContext) {
                ui.currContext.workingGraph = new Graph();
            }
            if(ui.paletteConfirmedGraph) {
                ui.paletteConfirmedGraph = new Graph();
            }
            util.empty(ui.paletteActions);
            util.empty(ui.paletteOptions);
            util.empty(ui.canvasActions);
            util.empty(ui.canvasOptions);
            util.empty(ui.paletteDisplay);
            util.empty(ui.canvasDisplay);
        }
        ui.currContext = cntxt;
        cntxt.init(cgURI);
    },
    //kill the palette and canvas levels?
    usePalette: function (palette, withActions) {
        
        if (ui.paletteDiv) {
            ui.paletteDiv.parentNode.removeChild(ui.paletteDiv);
        }
        
        this .currPalette = palette;
        this .currPalette.init();
        if (withActions) {
            this .currPalette.initActions();
            this .currPalette.initOps();
        }
    },

    useCanvas: function (canvas) {
        this .currCanvas = canvas;
        this .currCanvas.init();
    },
    
    
    init: function () {
        this .paletteActions = document.getElementById('palette-actions');
        this .canvasActions = document.getElementById('canvas-actions');
        this .paletteOptions = document.getElementById('palette-options');
        this .canvasOptions = document.getElementById('canvas-options');
        this .paletteContainer = document.getElementById('palette-container');
        this .canvasContainer = document.getElementById('canvas-container');
        this .paletteDisplay = document.getElementById('palette-display');
        this.paletteDisplay.gatherData = gatherPassThrough;
        this .canvasDisplay = document.getElementById('canvas-display');
        this .canvasSpinner = document.getElementById('canvasSpinner');
        this .paletteSpinner = document.getElementById('paletteSpinner');
        this.contextHeader = document.getElementById('context-container');
        this.helpDiv = document.getElementById('helpDiv');
        this.helpDiv.style.display = 'none';
        
        //just for testing
        this .currContextSubject = new Subject('http://example.com/exampleCG');
        this.currContextSubject.addPO('dcterms:title', util.makeLiteral('My Course Group' ));
    },
    
    closeHelp: function() {
        ui.helpDiv.style.display = 'none';
    },
    
    showHelp: function(event) {
        var hObj = event.target.helpObj;
        var lblH = document.getElementById('helpLabel');
        var txtDiv = document.getElementById('helpText');
        
        util.empty(lblH);
        util.empty(txtDiv);
        lblH.innerHTML = hObj.label;
        txtDiv.innerHTML = hObj.helpText;
        ui.helpDiv.style.display = 'block';
    },
    
    toggleHelp: function (event) {
        switch(ui.helpDiv.style.display) {
            case 'block':
                ui.closeHelp(event);
            break;
            case 'none':
                ui.showHelp(event);
            break;
        }
    
    }
};

/********************************
*
* Course Group Context
*
***********************************/



cgContext = {
    
    palettes: {
    },
    paletteWorkingGraph: new Graph(),
    canvasWorkingGraph: new Graph(),
    
    init: function (cgURI) {

        //palettes setup
        util.empty(ui.paletteDisplay);
        this.palettes['onlineInfoPalette'] = onlineInfoPalette.create();
         this.palettes['onlineInfoPalette'] .title = "Online Info";
        ui.currPalette = onlineInfoPalette;
        this .palettes[ 'isbnLookupPalette' ] = isbnLookupPalette.create();
        this. palettes[ 'isbnLookupPalette' ] . title = "ISBN Lookup";
        this .palettes[ 'isbnLookupPalette' ].style.display = 'none';
        
        this .palettes[ 'topicsLookupPalette' ] = topicsLookupPalette.create();
        this .palettes[ 'topicsLookupPalette' ].style.display = 'none';
        this .palettes[ 'topicsLookupPalette' ] . pred = 'geg:studiesTopic';
        this. palettes[ 'topicsLookupPalette' ] . title = 'Topic Lookup';
        
        this .palettes[ 'meansLookupPalette' ] = meansLookupPalette.create();
        this .palettes[ 'meansLookupPalette' ].style.display = 'none';
        this. palettes[ 'meansLookupPalette' ]. title = 'Tools Lookup';
        
        this .palettes[ 'perspectivesLookupPalette' ] = perspectivesLookupPalette.create();
        this .palettes[ 'perspectivesLookupPalette' ].style.display = 'none';
        this. palettes[ 'perspectivesLookupPalette' ].title = 'Perspectives Lookup';
        
        this .palettes[ 'practicesLookupPalette' ] = practicesLookupPalette.create();
        this .palettes[ 'practicesLookupPalette' ].style.display = 'none';        
        this. palettes[ 'practicesLookupPalette' ].title = 'Practices Lookup';
        
        for (var p in this .palettes) {
            ui.paletteDisplay.appendChild(this .palettes[p]);
        }
        

        
        //canvas setup
        ui.currCanvas = cgInfoCanvas;
        
        if (cgURI != null) {
            ui.currContextSubject = ajax.buildReq('getCGInfo.php', 'cgURI='+cgURI , cgContext.loadCGcb);
        } else {        
            this.initContextHeader();
            this .initPaletteActions();
            this .initPaletteOps();
            this. initTabs();
            ui.currCanvas.init();
        }
    },
    
    loadCGcb: function(response) {
            ui.currContextSubject = new Subject(response.currContextSubject);
            ui.currCanvas.workingGraph = new Graph();
            ui.currCanvas.workingGraph.importJSON(response.canvasWorkingGraph);
            ui.paletteWorkingGraph = new Graph();
            ui.paletteWorkingGraph.importJSON(response.canvasWorkingGraph);
    
            cgContext.initContextHeader();
            cgContext .initPaletteActions();
            cgContext .initPaletteOps();
            cgContext. initTabs();
            ui.currCanvas.init();    
    },
    
    initTabs: function() {
        util.empty( document.getElementById('tabs-container') );
        var exhibitTab = util.createTab();
        var p = document.createElement('p');
        var link = document.createElement('a');
        link.setAttribute('href', './Exhibits/CourseGroup/exhibit.php?filterByURI=' +ui.currContextSubject.subject );
        link.setAttribute('target', '_blank');
        link.appendChild(document.createTextNode('Go to Exhibit') );
        p.appendChild(link);
        exhibitTab.appendChild(p);
        document.getElementById('tabs-container').appendChild(exhibitTab);
    }, 
    
    initContextHeader: function() {
        util.empty(ui.contextHeader);
        var ctxtHeader = document.createElement('h1');
       ctxtHeader.appendChild(document.createTextNode(ui.currContextSubject.getTitle() ) );
       ui.contextHeader.appendChild(ctxtHeader);
        //ui.contextHeader.appendChild(document.createTextNode('Course Group') );
    },
    
    initPaletteActions: function () {
        util.empty(ui.paletteActions);
        //add in the actions
        var gatherActionP = document.createElement('p');
        // link to gather the checked boxes
//        gatherActionP.innerHTML = "Send &#10004;'d to canvas";
        gatherActionP.innerHTML = "Send checked right to double-check and save";
        gatherActionP.onclick = function() {
            ui.paletteDisplay.gatherData();
            if (! ui.currCanvas.workingGraph) {
                ui.currCanvas.workingGraph = new Graph();
            }
            ui.currCanvas.workingGraph.mergeGraph(ui.paletteConfirmedGraph );
            ui.currCanvas.render();
        };
        ui.paletteActions.appendChild(gatherActionP);
        

    },
    
    initPaletteOps: function () {
        
        //add in the options (e.g. for switching palettes within a context
        //this will get abstracted out as a common op
        var palSelect = document.createElement('select');
        
        for(var p in this.palettes) {
            var newOp = document.createElement('option');
            newOp.value = p ;
            newOp.appendChild(document.createTextNode(this.palettes[p].title) ) ;
            palSelect.appendChild(newOp);
        
        }

        
        
        palSelect.onchange = function () {
            
            for (var p in cgContext.palettes) {
                if (p != this .value) {
                    cgContext.palettes[p].style.display = 'none';
                } else {
                    cgContext.palettes[p].style.display = 'block';

                    ui.currPalette = eval( p ) ;                 
                    }        
                }            
        };
        
        var helpSpan = util.createHelpSpan(helpObjs.cgPalettes);
        ui.paletteOptions.appendChild(palSelect);
        ui.paletteOptions.appendChild(helpSpan);
    },
};

/***********************************
*
* Online Info Palette
*
*************************************/

onlineInfoPalette = {

    workingGraph: new Graph(),
    currResultsGraph: new Graph(),
    spinner: null,

    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        
        var paletteDiv = util.createPaletteDiv();       
        paletteDiv.gatherData = gatherPassThrough;
        
        ui.paletteDiv = paletteDiv;
    /*    var blogDiv = util.createInputCheckBox('Blog', 'geg:studiesByMeansOf');
        blogDiv.gatherData =  function() {
           var  inps = this.getElementsByTagName('input');
           if(inps[0].checked == true) {
           
               ui.currContextSubject.addPO(this.pred, util.makeURI( inps[1].value) );
           }
        };*/
        var blogDiv = lookupTemplates.anyURLLookup.create('Blog', 'geg:studiesByMeansOf', blogLookupResponse, helpObjs.blogURLLookup);
        

        
        
        paletteDiv.appendChild(blogDiv);
        
/*        paletteDiv.appendChild(lookupTemplates.anyURLLookup.create('Website', 'geg:studiesWithTool'));
        paletteDiv.appendChild(lookupTemplates.anyURLLookup.create('Flickr Account', 'geg:studiesWithTool'));
        paletteDiv.appendChild(lookupTemplates.anyURLLookup.create('Twitter Account', 'geg:studiesWithTool'));*/
        
     
        var tagDiv = util.createInputCheckBox('Class tag', 'geg:specialTag' , false,  helpObjs.specialTag);
        
        tagDiv.gatherData = function() {
           var  inps = this.getElementsByTagName('input');
           if(inps[0].checked == true) {
           
               ui.currContextSubject.addPO(this.pred, util.makeLiteral( inps[1].value) );
           }
        }
        
        paletteDiv.appendChild(tagDiv);
        
        
        this .resultsContainer = util.createPaletteResultsContainer();
        this.resultsContainer.gatherData = gatherPassThrough;
           
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },

};


/********************************
*
* ISBN LookupPalette
*
***********************************/

isbnLookupPalette = {
    
    workingGraph: new Graph(),
    currResultsGraph: new Graph(), //a graph containing only the most recent results
    spinner: null,
    
    
    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        var paletteDiv = util.createPaletteDiv();
        paletteDiv.pred = 'geg:studiesByMeansOf'; 
        paletteDiv.gatherData = gatherPassThrough;   
        
        ui.paletteDiv = paletteDiv;
        paletteDiv.appendChild(lookupTemplates.isbnLookup.create());
        this .resultsContainer = util.createPaletteResultsContainer();
        this. resultsContainer.pred = 'geg:studiesByMeansOf';
        this. resultsContainer.gatherData = gatherCheckedToContextSubjectAndConfirmedGraph ;         
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },
    
    
    
    finishCallback: function () {
        ui.paletteSpinner.style.display = 'none';
        var gDiv = graphDBpediaList.create(this .currResultsGraph);
        this .resultsContainer.appendChild(gDiv);
    }
}


/********************************
*
* practices Lookup Palette
*
***********************************/

practicesLookupPalette = {
    
    workingGraph: new Graph(),
    currResultsGraph: new Graph(), //a graph containing only the most recent results
    spinner: null,
    
    
    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        
        var paletteDiv = util.createPaletteDiv();
        paletteDiv.pred = 'geg:studiesWithPractice';
        paletteDiv.gatherData = gatherPassThrough;
        
        ui.paletteDiv = paletteDiv;
        paletteDiv.appendChild(lookupTemplates.dbpediaLookup.create());
        paletteDiv.appendChild(lookupTemplates.dbpediaPageQuery.create());
        this .resultsContainer = util.createPaletteResultsContainer();
        this. resultsContainer.pred = 'geg:studiesWithPractice';
        this. resultsContainer.gatherData = gatherPassThrough;     
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },
    
    finishCallback: function () {
        ui.paletteSpinner.style.display = 'none';
        var gDiv = graphDBpediaList.create(this .currResultsGraph);
        this .resultsContainer.appendChild(gDiv);
    }
}



/********************************
*
* perspectives Lookup Palette
*
***********************************/

perspectivesLookupPalette = {
    
    workingGraph: new Graph(),
    currResultsGraph: new Graph(), //a graph containing only the most recent results
    spinner: null,
    
    
    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        
        var paletteDiv = util.createPaletteDiv();
        paletteDiv.pred = 'geg:studiesFromPerspective';
        paletteDiv.gatherData = gatherPassThrough;
        
        ui.paletteDiv = paletteDiv;
        paletteDiv.appendChild(lookupTemplates.dbpediaLookup.create());
        paletteDiv.appendChild(lookupTemplates.dbpediaPageQuery.create());
        this .resultsContainer = util.createPaletteResultsContainer();
        this. resultsContainer.pred = 'geg:studiesFromPerspective';
        this. resultsContainer.gatherData = gatherPassThrough;
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },
    
    finishCallback: function () {
        ui.paletteSpinner.style.display = 'none';
        var gDiv = graphDBpediaList.create(this .currResultsGraph);
        this .resultsContainer.appendChild(gDiv);
    }
}




/********************************
*
* means Lookup Palette
*
***********************************/

meansLookupPalette = {
    
    workingGraph: new Graph(),
    currResultsGraph: new Graph(), //a graph containing only the most recent results
    spinner: null,
    
    
    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        
        var paletteDiv = util.createPaletteDiv();
        paletteDiv.pred = 'geg:studiesByMeansOf';
        paletteDiv.gatherData = gatherPassThrough;
        
        ui.paletteDiv = paletteDiv;
        paletteDiv.appendChild(lookupTemplates.dbpediaLookup.create());
        paletteDiv.appendChild(lookupTemplates.dbpediaPageQuery.create());
        var anyURLDiv = lookupTemplates.anyURLLookup.create('Resource At', 'geg:studiesByMeansOf', testAnyURLResponse);
        
        paletteDiv.appendChild(anyURLDiv);
      //  paletteDiv.appendChild(lookupTemplates.anyURLLookup.create() );
        this .resultsContainer = util.createPaletteResultsContainer();
        this. resultsContainer.pred = 'geg:studiesByMeansOf';
        this. resultsContainer.gatherData = gatherPassThrough;
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },
    
    finishCallback: function () {
        ui.paletteSpinner.style.display = 'none';
        var gDiv = graphDBpediaList.create(this .currResultsGraph);
        this .resultsContainer.appendChild(gDiv);
    }
}




/********************************
*
* topics Lookup Palette
*
***********************************/

topicsLookupPalette = {
    
    workingGraph: new Graph(),
    currResultsGraph: new Graph(), //a graph containing only the most recent results
    spinner: null,
    
    
    create: function () {
        // makes its palette div and stuffs it into ui.paletteContainer
        
        var paletteDiv = util.createPaletteDiv();
        paletteDiv.gatherData = gatherPassThrough;
        
        ui.paletteDiv = paletteDiv;
        paletteDiv.appendChild(lookupTemplates.dbpediaLookup.create());
        paletteDiv.appendChild(lookupTemplates.dbpediaPageQuery.create());
        
        var anyURLDiv = lookupTemplates.anyURLLookup.create('Resource At', 'geg:studiesByMeansOf', testAnyURLResponseNoTypes);
        paletteDiv.appendChild(anyURLDiv);
        
        this .resultsContainer = util.createPaletteResultsContainer();
        this. resultsContainer.pred = 'geg:studiesTopic';
        this. resultsContainer.gatherData = gatherPassThrough;
        // attach a reference to the palette, so ui can look at it: ui.currPalette.resultsContainer
        paletteDiv.appendChild(this .resultsContainer);
        return paletteDiv;
    },
    
    finishCallback: function () {
        ui.paletteSpinner.style.display = 'none';
        var gDiv = graphDBpediaList.create(this .currResultsGraph);
        this .resultsContainer.appendChild(gDiv);
    }
}






/********************************
*
* Course Group Info Canvas
*
***********************************/

cgInfoCanvas = {
   // workingGraph: new Graph(),
    insertGraph: new Graph(),
    resultsContainer: {
    },
    
    init: function () {
        //makes its canvasDiv and stuffs it into ui.canvasContainer
        if ( ! this.workingGraph ) {
            this .workingGraph = new Graph();
        }
        
        this .resultsContainer = util.createCanvasDiv();
        ui.canvasContainer.appendChild(this .resultsContainer);
        this .workingGraph.addSubject(ui.currContextSubject);
        
        
        //makes its actions and stuffs them into ui.canvasActions
        var gatherActionP = document.createElement('p');
        gatherActionP.appendChild(document.createTextNode('Save'));
        //TODO switch this to use the gatherData approach.
        gatherActionP.onclick = cgInfoCanvas.makeInsertGraph;
        ui.canvasActions.appendChild(gatherActionP);
        this.render();
    },
    
    makeInsertGraph : function () {
        ui.canvasSpinner.style.display = 'block';
        cgInfoCanvas.insertGraph = new Graph();
      var divs = ui.canvasDisplay.getElementsByTagName('div');
        for (var d = 0 ; d < divs.length; d++ ) {
            if (divs[d].gatherData) {
                divs[d].gatherData();
            }        
        }
    
        var sArray = ui.currCanvas.insertGraph.getObjs4Pred('skos:subject');
        
            for(var i = 0; i<sArray.length ; i ++) {
                if(sArray[i] != false) {
                    ui.currCanvas.insertGraph.addSubject(ui.currContext.paletteWorkingGraph.subjects[sArray[i] ]) ;
                }
            }
        var sArray = ui.currCanvas.insertGraph.getObjs4Pred('dc:creator');
        
            for(var i = 0; i<sArray.length ; i ++) {
                if(sArray[i] != false) {
                    ui.currCanvas.insertGraph.addSubject(ui.currContext.paletteWorkingGraph.subjects[sArray[i] ]) ;
                }
            }
        
    
        var cb = function(resp) {
        //TODO: fill this in
            alert('Saved ' + resp.count + ' pieces of info to the store.  Raw Data Now!' );
            ui.canvasSpinner.style.display = 'none';
        };
    
        cgInfoCanvas.insertGraph.mergeGraph(ui.paletteConfirmedGraph);
    
        cgInfoCanvas.insertGraph.pseudoInfer();
        cgInfoCanvas.insertGraph.mergeGraph(ui.currContextSubject.pseudoInfer() );
        
        
        var ntriples = encodeURIComponent(  ui.currContextSubject.toNT() + cgInfoCanvas.insertGraph.toNT() );
    
        
        ajax.buildReq('addToStore.php', 'ntriples='  + ntriples , cb);        
    },
    
    render: function () {
        util.empty(ui.canvasDisplay);
        
        //set up the containers
        var studyThingsDiv = document.createElement('div');
        
        
        var topicsDiv = document.createElement('div');
        topicsDiv.setAttribute('class', 'studyThings');
        var heading = document.createElement('h1');
        heading.appendChild(document.createTextNode('Topics'));
        topicsDiv.appendChild(heading);
        
        
        var perspectivesDiv = document.createElement('div');
        perspectivesDiv.setAttribute('class', 'studyThings');
        var heading = document.createElement('h1');
        heading.appendChild(document.createTextNode('Perspectives'));
        perspectivesDiv.appendChild(heading);
        
        
        
        var meansDiv = document.createElement('div');
        meansDiv.setAttribute('class', 'studyThings');
        var heading = document.createElement('h1');
        heading.appendChild(document.createTextNode('Tools and Texts'));
        meansDiv.appendChild(heading);
        
        
        
        var practicesDiv = document.createElement('div');
        practicesDiv.setAttribute('class', 'studyThings');
        var heading = document.createElement('h1');
        heading.appendChild(document.createTextNode('Practices'));
        practicesDiv.appendChild(heading);
        
        
        
        //template the results
        
        //template means
        var meansUL = document.createElement('ul');
        var oArray = ui.currContextSubject.getObjs4Pred('geg:studiesByMeansOf');
        for (var i = 0; i < oArray.length; i++) {
            var s = ui.currCanvas.workingGraph.subjects[oArray[i] ];
            
            var sEl = titleLITemplate.create(s);
            if (s.isRemoved) {
                titleLITemplate.toggleRemove(sEl);
            }
            meansUL.appendChild(sEl);
        }
        meansDiv.appendChild(meansUL);
        
        
        //template practices
        practicesUL = document.createElement('ul');
        var oArray = ui.currContextSubject.getObjs4Pred('geg:studiesWithPractice');
        for (var i = 0; i < oArray.length; i++) {
            var s = ui.currCanvas.workingGraph.subjects[oArray[i] ];
            var sEl = titleLITemplate.create(s);
            if (s.isRemoved) {
                titleLITemplate.toggleRemove(sEl);
            }
            practicesUL.appendChild(sEl);
        }
        practicesDiv.appendChild(practicesUL);
        
        //template perspectives
        perspectivesUL = document.createElement('ul');
        var oArray = ui.currContextSubject.getObjs4Pred('geg:studiesFromPerspective');
        for (var i = 0; i < oArray.length; i++) {
            var s = ui.currCanvas.workingGraph.subjects[oArray[i] ];
            var sEl = titleLITemplate.create(s);
            if (s.isRemoved) {
                titleLITemplate.toggleRemove(sEl);
            }
            perspectivesUL.appendChild(sEl);
        }
        perspectivesDiv.appendChild(perspectivesUL);
        
        
        //template topics
        topicsUL = document.createElement('ul');
        var oArray = ui.currContextSubject.getObjs4Pred('geg:studiesTopic');
        for (var i = 0; i < oArray.length; i++) {
            var s = ui.currCanvas.workingGraph.subjects[oArray[i] ];
            var sEl = titleLITemplate.create(s);
            if (s.isRemoved) {
                titleLITemplate.toggleRemove(sEl);
            }
            topicsUL.appendChild(sEl);
        }
        topicsDiv.appendChild(topicsUL);
        
        
        //add to studyThingsDiv
        topicsDiv.gatherData = gatherLIToInsertGraph;
        topicsDiv.pred = 'geg:studiesTopic';
        studyThingsDiv.appendChild(topicsDiv);        
        
        meansDiv.gatherData = gatherLIToInsertGraph;
        meansDiv.pred = 'geg:studiesByMeansOf';
        studyThingsDiv.appendChild(meansDiv);
        
        perspectivesDiv.gatherData = gatherLIToInsertGraph;
        perspectivesDiv.pred = 'geg:studiesFromPerspective';
        studyThingsDiv.appendChild(perspectivesDiv);
        
        practicesDiv.gatherData = gatherLIToInsertGraph;
        practicesDiv.pred = 'geg:studiesWithPractice';
        studyThingsDiv.appendChild(practicesDiv);
        
        ui.canvasDisplay.appendChild(studyThingsDiv);
    }
}






/************************
*
* Create Course Group Context
*
****************************/

createCGContext = {

    init: function() {
        var cb = function(resp) {
            instGraph = new Graph();
            instGraph.importJSON(resp);
            var pal = createCGPalette.create();
            ui.paletteDisplay.appendChild(pal);
        };
        ajax.buildReq('getKnownInstitutions.php', '', cb);

    
        this.initPaletteActions();
        this.initContextHeader();
    },
    
    initContextHeader: function() {
        util.empty(ui.contextHeader);
        var ctxtHeader = document.createElement('h1');
       ctxtHeader.appendChild(document.createTextNode('Create New Course Group' ) );
       ui.contextHeader.appendChild(ctxtHeader);   
    },
    
    initPaletteActions: function() {
        var createActionP = document.createElement('p');
        createActionP.appendChild(document.createTextNode('Create Class') );
        createActionP.onclick = function() {
           ui.error = false; 
           ui.paletteDisplay.gatherData();
       
            if ( ui.error == false ) {
                //switch canvas
       
                ui.useContext(cgContext);
             
            
            } else {
              
             alert(ui.error);
            }
        
        };
        
        ui.paletteActions.appendChild(createActionP);
    
    }


};


/************************
*
* Create Course Group Palette
*
****************************/

createCGPalette = {

    newCourse : new Subject() ,
    

    create: function() {
        var palDiv = util.createPaletteDiv();
        var palHeading = document.createElement('h1');
        ui.currPalette = this;
        palHeading.appendChild(document.createTextNode('Create a new class') );
        
    var helpSpan = util.createHelpSpan(helpObjs.createCG);
    palHeading.appendChild(helpSpan);
        
        palDiv.appendChild(palHeading);
        
        /*
        *
        * this.newCourse is empty object until the creation happens
        * then it gets replaced with a real subject
        * and the refs add data when gatherData is called on the divs
        * (hopefully this will work!)
        *
        */
        
        //title
        var titleDiv =  util.createBasicInput('Title', 'dcterms:title', true);
        titleDiv.gatherData = gatherValueToRef;
        titleDiv.ref = createCGPalette.newCourse;        
        palDiv.appendChild( titleDiv );
        
        //baseID
         var baseIDDiv = util.createBasicInput('Base ID / Dept', 'geg:baseID', true);
         baseIDDiv.gatherData = gatherValueToRefUC;
         
         baseIDDiv.ref = this.newCourse;         
        palDiv.appendChild( baseIDDiv );
        
        //course number
        var courseNumberDiv =  util.createBasicInput('Number', 'geg:courseNumber', true );
        courseNumberDiv.gatherData = gatherValueToRef;
        courseNumberDiv.ref = this.newCourse;        
        palDiv.appendChild( courseNumberDiv);
        
        //extension
        
        //extension might need to handle the relationship between the basic course and the course with the extension?
        var extDiv = util.createBasicInput('Extension', 'geg:extension');
        extDiv.gatherData = gatherValueToRef;
        extDiv.ref = this.newCourse;
        palDiv.appendChild( extDiv );
        
        //sections matter to the course groups, but are all the same course
        //this calls for multiple ui.currContextSubject, or some more sneaky way at dealing with it.
        var sections =  util.createBasicInput('Sections', 'geg:section', true);
        sections.gatherData = function() {};
        palDiv.appendChild( sections );
        

        var termDiv = util.createSelect('Term ', 'geg:term', termsGraph, true, false, 1 );
        termDiv.childNodes[2].selectedIndex = 1;
        termDiv.appendChild(util.createHelpSpan(helpObjs.term) );

        palDiv.appendChild( termDiv );
        instGraph.sortByLabel();
        var instSelectDiv = util.createSelect('Institution ', 'geg:institution', instGraph, true, false, 1);
        var sel = instSelectDiv.getElementsByTagName('select')[0];
        var labelOpt = document.createElement('option');
        labelOpt.value = false;
        labelOpt.appendChild(document.createTextNode('Choose from known institutions') );
        sel.insertBefore(labelOpt, sel.firstChild);
        labelOpt.selected = true;
        palDiv.appendChild( instSelectDiv );
        
        
        var instLookupDiv = lookupTemplates.dbpediaInstLookup.create() ;
        instLookupDiv.pred = 'geg:institution';
        instLookupDiv.ref = this.newCourse;
        instLookupDiv.gatherData = gatherCheckedToRefAndConfirmedGraph;
        palDiv.appendChild(instLookupDiv);
        this.resultsContainer = util.createPaletteResultsContainer() ;
        this.resultsContainer.setAttribute('class', 'paletteResults-createCG');
        this.resultsContainer.gatherData =  gatherCheckedToRefAndConfirmedGraph ; 
        this.resultsContainer.ref = this.newCourse;
        this.resultsContainer.pred = 'geg:institution';
        palDiv.appendChild(this.resultsContainer) ;
        
        
        palDiv.gatherData = function() {
            var inps = this.getElementsByTagName('input');
   
       
            var title = inps[0].value;
            var baseID = inps[1].value.toUpperCase();
            var number = inps[2].value;
            var ext = inps[3].value;
          
            //will need to parse sections to #s
            var sectionsList = inps[4].value.split(',');
            var section = parseInt(sectionsList[0] );
            //TODO: figure out dealing with multiple sections.
            
            
            
            var termURI = this.getElementsByTagName('select')[0].value.stripSlash();
            
            var instSelect = this.getElementsByTagName('select')[1];
            if (instSelect.selectedIndex != 0 ) {            
                var instURI = instSelect.value.stripSlash();
            } else {
                var instInpts = ui.currPalette.resultsContainer.getElementsByTagName('input');
                for (var insti = 0 ; insti < instInpts.length; insti++ ) {
                    if ( instInpts[insti].checked ) {
                    //TODO: deal with more than one selection
                        var instURI = instInpts[insti].parentNode.ref.subject ;
                    }                
                }            
            }                                   
            
          if( (instURI == '' ) || (termURI == '' ) || (section == '' ) || (title == '' ) || (baseID == '' ) || (number == '' ) ) {
                ui.error = 'Oops!  Make sure all the required data is there.';
                  
              return false;
          }
        
          
            var cgURI = mint.cgURI(baseID, number, instURI, section, termURI, ext);
            var courseURI = mint.courseURI(baseID, number, instURI, ext);

            
            ui.currContextSubject = new Subject(cgURI);                        
            createCGPalette.newCourse.resetURI(courseURI);

            createCGPalette.newCourse.addPO('rdf:type', util.makeURI('geg:Course') );
            ui.currContextSubject.addPO('geg:courseGroupOf', util.subjectToObject(createCGPalette.newCourse) );
            ui.currContextSubject.addPO('geg:institution', util.makeURI(instURI) );
            ui.currContextSubject.addPO('geg:section', util.makeLiteral(section) );
            ui.currContextSubject.addPO('dcterms:title', util.makeLiteral(title) );
            ui.currContextSubject.addPO('rdf:type', util.makeURI('geg:CourseGroup') );
            ui.paletteConfirmedGraph.addSubject(createCGPalette.newCourse);            


           //a graph holding the additional sections, where most all of the data is the same as for the 'base' section
            ui.parallelSectionsGraph = new Graph(); 
            for (var sects = 1 ; sects < sectionsList.length; sects++) {
                var section = parseInt( sectionsList[sects] ) ;
                var pCGURI = mint.cgURI(baseID, number, instURI, section, termURI, ext);
                var newSubject = new Subject(pCGURI);
                newSubject.addPO('geg:courseGroupOf', util.subjectToObject(createCGPalette.newCourse) );
                newSubject.addPO('geg:institution', util.makeURI(instURI) );
                newSubject.addPO('geg:section', util.makeLiteral(section) );
                newSubject.addPO('dcterms:title', util.makeLiteral(title) );
                newSubject.addPO('rdf:type', util.makeURI('geg:CourseGroup') );                
                ui.parallelSectionsGraph.addSubject(newSubject);
            }

            gatherPassThrough(this);
            return true;
        }
        return palDiv;
    }


};




/********************************
*
* Create Person Context
*
***********************************/

createPersonContext = {
    
    palettes: {
    },
    
    init: function () {
        ui.currContextSubject = null;
        
        //palette setup
        this .palettes[ 'createPersonPalette' ] = createPersonPalette;
        
        ui.currPalette = createPersonPalette;
        var palDiv = this .palettes[ 'createPersonPalette' ].create();
        
        ui.paletteDisplay.appendChild(palDiv);
        
        //actions
        createPersonContext.initPaletteActions();
    },
    
    initPaletteActions: function () {
        util.empty(ui.paletteActions);
        var createP = document.createElement('p');
        createP.appendChild(document.createTextNode('Create'))
        createP.onclick = createPersonPalette.createAction;
        ui.paletteActions.appendChild(createP);
    },
};

/********************************
*
* Create Person Palette
*
***********************************/

createPersonPalette = {
    
    create: function () {
        var palDiv = document.createElement('div');
        ui.currPalette = this;
        
        
        //email
        var emailDiv = util.createBasicInput('Email: ');
        
        var firstDiv = util.createBasicInput('First Name: ');
        var lastDiv = util.createBasicInput('Last Name: ');
        
        palDiv.appendChild(emailDiv);
        palDiv.appendChild(firstDiv);
        palDiv.appendChild(lastDiv);
        
        return palDiv;
    },
    
    createAction: function () {
        
        var inpts = ui.paletteDisplay.getElementsByTagName('input');
        
        var emailHash = hex_sha1(inpts[0].value);
        var uri = 'http://www.ravendesk.org/geg/People/' + emailHash;
        ui.currContextSubject = new Subject(uri);
        ui.currContextSubject.addPO('foaf:firstName', util.makeLiteral(inpts[1].value));
        ui.currContextSubject.addPO('foaf:lastName', util.makeLiteral(inpts[2].value));
        
        ui.useContext(personContext);
    }
};




/********************************
*
* Person Context
*
***********************************/


personContext = {
    
    
    init: function () {
        util.empty(ui.paletteDisplay);
        
        ui.paletteDisplay.appendChild(personPalette.create());
        
        
        this .initPaletteActions();
    },
    
    initPaletteActions: function () {
        util.empty(ui.paletteActions);
        var saveP = document.createElement('p');
        saveP.appendChild(document.createTextNode('Send To Canvas'));
        saveP.onclick = personPalette.sendToCanvasAction;
        ui.paletteActions.appendChild(saveP);
    }
}

/********************************
*
* Person Palette
*
***********************************/

personPalette = {
    workingGraph: new Graph(),
    
    create: function () {
        var palDiv = document.createElement('div');
        ui.currPalette = this;
        
        //weblog
        palDiv.appendChild(util.createBasicInput('Blog', util.expandPrefix('foaf:weblog') ));
        
        //image
        palDiv.appendChild(util.createBasicInput('Image/Avatar URL', util.expandPrefix('foaf:img') ));
        
        
        //interests (dbpedia lookup
        var interestsDiv = document.createElement('div');
        var intH = document.createElement('h1');
        intH.appendChild(document.createTextNode('Interests'))
        interestsDiv.appendChild(intH);
        interestsDiv.contextPred = util.expandPrefix('foaf:interest' );
        
        interestsDiv.appendChild(lookupTemplates.dbpediaLookup.create());
        var predResultsDiv = document.createElement('div');
        predResultsDiv.setAttribute('class', 'predResults');
        this .dbpediaCallback.container = predResultsDiv;
        interestsDiv.appendChild(predResultsDiv);
        lookupTemplates.dbpediaLookup.callback = this .dbpediaCallback;
        
        
        palDiv.appendChild(interestsDiv);
        return palDiv;
    },
    
    dbpediaCallback: function () {
      
        var respGraph = new Graph();
        respGraph.importJSON(dbplookup);
        
        
        for (var sURI in respGraph.subjects) {
            var s = respGraph.subjects[sURI];
            s.isRemoved = false;
            var sLI = document.createElement('li');
            var sDiv = dbpediaConfirm.create(s);
            
            sLI.appendChild(sDiv);
            personPalette.dbpediaCallback.container.appendChild(sDiv);
        }
        
        ui.paletteSpinner.style.display = 'none';
    },
    
    sendToCanvasAction: function () {
        var divs = ui.paletteDisplay.getElementsByTagName('div');
        for(var i = 0; i<divs.length; i++) {
        //if it has a contextPred, it's getting added
        //TODO refactor!!!
        //make sure I handle no data
            if (divs[i].contextPred) {
                switch (divs[i].contextPred) {
                    //branching around different actions for 
                    case util.expandPrefix('foaf:img'):
                    case util.expandPrefix('foaf:weblog'):
                        var inputs = divs[i].getElementsByTagName('input');
                        for (var j =0; j<inputs.length; j++) {
                            ui.currContextSubject.addPO(divs[i].contextPred, util.makeURI(inputs[j].value ) );
                        }
                    break;
  
                    case util.expandPrefix('foaf:interest'):
                        var inputs = divs[i].getElementsByTagName('input');
                        for (var i in inputs) {
                            if (inputs[i].checked == true) {
                                ui.currPalette.workingGraph.addSubject(inputs[i].parentNode.ref);
                                var newObj = util.makeURI(inputs[i].parentNode.ref.subject);
                                ui.currContextSubject.addPO('foaf:interest', newObj);
                            }
                        }
                    break;
                }
            }
        }
        
        

        //pull out weblog URLs
        //pull out foaf:imgs
        
        //multiple objects will get implemented someday, so treat as array now
        //need the callback to have it move through the array
        
        
        var blogsArr = ui.currContextSubject.getObjs4Pred('foaf:weblog');
        
     //   personPalette.reqQueue = personPalette.reqQueue.concat(blogsArr);
        
        
        
        for(var i in blogsArr) {
          ajax.buildReq('anyURLLookup.php', 'lookupURL=' + encodeURIComponent(blogsArr[i] ), callbacks.addResultToPalette);        
        }
    
    //basically a callback for ajax.finishReqs
    ajax.finish = function() {
    
        alert('Im almost ready to do something useful!');
    };
    
    ajax.finishReqs();

    }
    
    
};




//common callbacks
var callbacks = {
};




callbacks.addResultToPalette = function (response) {
    
    ui.currPalette.workingGraph.importJSON(response);
    
  
    //yeah, i suck.  commented out below until I can figure out if I'm actually using it anywhere
    
/*    if (ui.currPalette.currResultsGraph) {
        ui.currPalette.currResultsGraph = new Graph();
        ui.currPalette.currResultsGraph.importJSON(response);
    }
    ui.currPalette.finishCallback();*/
}

//common actions


var actions = {
};

actions.gatherCheckedInContainer = function (container) {
    var gatheredGraph = new Graph();
    var inputs = container.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].checked) {
            gatheredGraph.addSubject(inputs[i].parentNode.ref);
        }
    }
    return gatheredGraph;
}

actions.sendCheckedToCanvas = function () {
    var inputs = ui.currPalette.resultsContainer.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].checked) {
            //need to branch around whether I'm grabbing a literal or uri
            //NOPE!  checked are always subjects!  But I'll need it for creation inputs!
            var pred = util.expandPrefix(inputs[i].parentNode.contextPred);
            var inputS = inputs[i].parentNode.ref;
            
            var uriObjs = inputS.getURIObjects();
            for (var j = 0; j < uriObjs.length; j++) {
                if (ui.currPalette.workingGraph.subjects[uriObjs[j] ] instanceof Subject) {
                    ui.currCanvas.workingGraph.addSubject(ui.currPalette.workingGraph.subjects[uriObjs[j] ]);
                }
            }
            ui.currCanvas.workingGraph.addSubject(inputS);
            
            //this adds a triple to connect the contextSubject with the new resource
            // but seems to be making duplications
            var o = {
            };
            o.value = inputS.subject;
            o.type = 'uri';
            ui.currContextSubject.addPO(pred, o);
        }
    }
    
    
    ui.currCanvas.render();
}