/* Contains functions used by BuildCollection.js and ListCollections.js
 */
LLDL.Bean.FlaxCollection = function(config, collection_metadata) {
    this.config_info = config;
    this.meta = collection_metadata;
    
    var build_type_xml = LLDL.getNamedElement(this.config_info.collection_build_xml.getElementsByTagName('buildTypeList')[0], 'buildType', 'name', this.meta.build);
    this.build_section_map = this.getBuildSectionMap(build_type_xml);
    this.doc_map = this.processDocMap(this.meta['docList']);
    this.collocation = this.processCollocation(this.meta['collocation']);
    this.getBody();
};
LLDL.Bean.FlaxCollection.prototype = {
	getCollname: function() {
		return this.meta.collname;
	},
	processDocMap: function(doc_list_el) {
        var doc_map = new HashMap();
        var doc_list = doc_list_el.getElementsByTagName('doc');
        for(var doc, i=0; i<doc_list.length; i++) {
            doc = doc_list[i];
            var doc_id = doc.getAttribute('Identifier');
            var title = LLDL.getDomFirstChildTextNodeValue(doc, 'Title');
            var level = LLDL.getDomFirstChildTextNodeValue(doc, 'Level');
            var num_paras = LLDL.getDomFirstChildTextNodeValue(doc, 'numParas');
            var num_words = LLDL.getDomFirstChildTextNodeValue(doc, 'numWords');
            var o = {Identifier:doc_id, Title:title, Level:level, Content:'content omitted', numParas:num_paras, numWords:num_words};
            doc_map.put(doc_id, new LLDL.Bean.FlaxDocument(this.config_info, o));
        }
        
        // Extract levels to choose from
        var all_levels = LLDL.getDomFirstChildTextNodeValue(doc_list_el, 'chooseFromLevels');
        this.choose_from_levels = all_levels.split(',');
        return doc_map;
    },
    processCollocation: function(collo_metadata_el) {
	    var extract_collo = collo_metadata_el.getAttribute('value');// '1' or '0'
	    var collocation = new HashMap();
	    collocation.put('collocation', {name:'collocation', value:extract_collo});

        var metalist = collo_metadata_el.getElementsByTagName('meta');    
        var name, title, value;
        for(var i=0; i<metalist.length; i++) {
            var m = metalist[i];
            //The name of the meta
            name = m.getAttribute('name');
            //An obj containing all info about this meta
            var value_obj = {name:name};
            var itemlist = m.getElementsByTagName('displayItem');
            var items = [];
            for(var k=0; k<itemlist.length; k++) {
                items.push({value:itemlist[k].getAttribute('value'), title:itemlist[k].firstChild.data});
            }
            value_obj.items = items;
            
            //Are there other attributes of the meta?
            var atts = m.attributes;//Array of attribute objects
            for(var k=0; k<atts.length; k++) {
            	var a = atts[k];
            	if(a.name=='name') continue;
            	value_obj[a.name] = a.value;
            }
            collocation.put(name, value_obj);             
        }
        return collocation;
    },
    getBody: function() {
    	this.tobuild_icon = LLDL.createEl('img');
    	this.tobuild_icon.setAttribute('id', 'tobuild_'+this.getCollname());
    	this.tobuild_icon.setAttribute('src', this.config_info.images_url+'warn16_1.gif');
    	this.tobuild_icon.setAttribute('title', 'Collection needs rebuild');
    	yud.addClass(this.tobuild_icon, 'tobuild_icon');
        this.body = LLDL.createEl('li', this.getCollname());
        this.body.appendChild(this.tobuild_icon);
        this.title_el = LLDL.createInnerHTML('div', '', this.meta.title, 'coll_title'); 
		this.body.appendChild(this.title_el);
       
        var btn_panel = LLDL.createEl("div",'','','coll_btns_panel');
        this.body.appendChild(btn_panel);
        this.edit_btn = this.createBtn({id:'edit_'+this.getCollname(),
	         text:'edit',
	         styles:'visibility:visible',
	         tooltip:'Edit collection'});
        this.delete_btn = this.createBtn({id:'del_'+this.getCollname(),
	         text:'delete',
	         styles:'visibility:visible',
	         tooltip:'Delete collection'});
        this.copy_btn = this.createBtn({id:'copy_'+this.getCollname(),
	         text:'copy',
	         styles:'visibility:visible',
	         tooltip:'Make a copy of this collection, hidden from students'});
        this.preview_btn = this.createBtn(
	        {id:'preview_'+this.getCollname(),
	         text:'preview',
	         styles:'visibility:visible',
	         tooltip:'Preview collection in a new window'});
        btn_panel.appendChild(this.edit_btn);
        btn_panel.appendChild(this.delete_btn);
        btn_panel.appendChild(this.copy_btn);
        btn_panel.appendChild(this.preview_btn);
//        var html = '';
//        if(this.meta.category==lbb.c3 || this.meta.category==lbb.c4) {
//        	//edit and delete buttons are displayed for private and tobuild collections only
//        	html = 
//	        '<a collbtn="true" style="visibility:visible;" id="edit_'+this.getCollname()+'" '+
//	              'title="Edit collection">' +
//	              'edit</a>' +
//	        '<a collbtn="true" style="visibility:visible;" id="del_'+this.getCollname()+'" '+
//	              'title="Delete collection">' +
//	              'delete</a>';        	
//        }
//        //always display the copy button
//        html += '<a collbtn="true" style="visibility:visible;" id="copy_'+this.getCollname()+'"' +
//              'title="Make a copy of this collection, hidden from others">' +
//              'copy</a>';
//        btn_panel.innerHTML = html;
//              
//        if(!this.config_info.mdlusername) {//not display the preview button for moodle module version
//          if(this.meta.category!=lbb.c4){//only when the collection is ready to use
//	        this.preview_btn = LLDL.createEl('a', 'preview_'+this.getCollname(), 'preview');
//	        this.preview_btn.setAttribute('collbtn', 'true');
//	        this.preview_btn.setAttribute('title', 'Preview collection in a new window');
//        	btn_panel.appendChild(this.preview_btn);
//          }
//        }
        this.updateStyle();//set style in accordance with its category and whether it's in moodle or standalone
        return this.body;
    },
    createBtn: function(o) {
        var btn = LLDL.createEl('a', o.id, o.text);
        btn.setAttribute('collbtn', 'true');
        btn.setAttribute('style', o.styles);
        btn.setAttribute('title', o.tooltip);
        return btn;
    },
    setCategory: function(cate) {
    	this.meta.category = cate;
    },
    refresh: function() {
    	this.updateTitle();
    	this.updateStyle();
    },
    updateTitle: function() {
    	this.title_el.innerHTML = this.meta.title;//this is important, as the title might have been modified when it's being edited
    },
    updateStyle: function() {
    	yud.setStyle(this.tobuild_icon, 'visibility', (this.meta.category==lbb.c4)?'visible':'hidden');
    	
    	var tooltip = '';
    	if(this.meta.category == lbb.c1 || this.meta.category == lbb.c2) {
    		tooltip = 'This collection is ready to use';
    	}else if(this.meta.category == lbb.c3) {
    		tooltip = 'Collection is ready but hidden';
    	}else{
    		tooltip = 'This collection cannot be moved because it hasn\'t been built yet. Click \'edit\' then build the collection.';
    	}
    	this.title_el.setAttribute('title', tooltip);
    	yud.setStyle(this.title_el, 'cursor', (this.meta.category!=lbb.c4)?'move':'auto');
    	
    	if(this.meta.category==lbb.c3 || this.meta.category==lbb.c4) {
    		//edit and delete buttons are displayed for private and tobuild collections only
    		yud.setStyle(this.edit_btn, 'visibility', 'visible');
    		yud.setStyle(this.delete_btn, 'visibility', 'visible');
    	}else{
    		yud.setStyle(this.edit_btn, 'visibility', 'hidden');
    		yud.setStyle(this.delete_btn, 'visibility', 'hidden');
    	}
    	
    	if(this.config_info.mdlusername) {//not display the preview button for moodle module version
        	yud.setStyle(this.preview_btn, 'visibility', 'hidden');
        }else{
        	yud.setStyle(this.preview_btn, 'visibility', (this.meta.category!=lbb.c4)?'visible':'hidden');
        }
    },
    getBuildSectionMap: function(build_type_xml) {
    	var map = new HashMap();
    	
        var section_list = build_type_xml.getElementsByTagName('section');
    	for(var i=0; i<section_list.length; i++) {
    		var sec = section_list[i];
    		var sec_name = sec.getAttribute('name');
    		map.put(sec_name, {name:sec_name, step:sec.getAttribute('step'), activityList:sec.getAttribute('activityList')});
    	}
    	return map;
    },
    showBuildNotice: function(success) {
    	var coll_build_notice = (success)?((this.config_info.mdlusername)? lbb.move_coll_notice_mdl : lbb.move_coll_notice):lbb.fail_build_notice;
        var notice = LLDL.createInnerHTML('div','coll_build_notice',
        '<div class="hd">' +
        '<img src="'+this.config_info.images_url+'delete.gif"/>' +
        '<span>'+this.meta.title+'</span>' +
        '<br/><br/>'+coll_build_notice+'</div>', 'coll_build_notice');
        yud.insertAfter(notice, this.body.parentNode);
        var panel = new YAHOO.widget.Panel(notice, {
        	close:false,
        	visible:true,
        	draggable:false,
        	effect: {effect:YAHOO.widget.ContainerEffect.FADE, duration: 1 }
        });
        panel.render();
        yue.on(document.body, 'mousedown', function() {
        	panel.hide();
        }, this, true);
    }
};

LLDL.Bean.FlaxDocument = function(config, o) {//FlaxDocument object definition is used in BuildCollection.js
    /**
     * Points where encoding/decoding are done: 
     * 1. decoding: here and queryDocContentCallback()
     * 2. encoding: sendDocToServer()
     */
    this.config_info = config;
    this.Identifier = o.Identifier;
    this.Title = decodeURIComponent(o.Title);
    //decodeURIComponent() causes malformed URI sequence thrown in Firefox when o.Content contains special characters like %
    this.Content = unescape(o.Content);//this.Content contains <p> ... </p>, i.e., it has been marked with paragraph tags
    this.Level = decodeURIComponent(o.Level);
    this.numParas = o.numParas;
    this.numWords = o.numWords;
    
    this.body = this.getDocBody();
};
LLDL.Bean.FlaxDocument.prototype = {
    getDocBody: function() {
        var body = LLDL.createEl('tr', 'doc_'+this.Identifier);
        var doc_btns = LLDL.createInnerHTML('td','',
	            '<a docbtn="true" id="'+this.Identifier+'_edit" title="Edit document">edit</a>' +
	            '<a docbtn="true" id="'+this.Identifier+'_del" title="Delete document">delete</a>','doc_btns');
        body.appendChild(doc_btns);
        this.getDocInfoHTML(body);
        return body;    
    },
    getDocDisplayBody: function(order_number) {//used to present info in the 'Build' panel (a list of document info)
        var body = LLDL.createEl('tr', this.Identifier);
        var doc_number = LLDL.createInnerHTML('td','',order_number);
        body.appendChild(doc_number);
        this.getDocInfoHTML(body);
        return body;    
    },
    getDocInfoHTML: function(body) {
    	this.title_el = LLDL.createEl('td','',this.Title,'doc_title_cell_class');
    	this.level_el = LLDL.createEl('td','',this.Level);
    	this.num_paras_el = LLDL.createEl('td', '', ''+this.numParas);
    	this.num_words_el = LLDL.createEl('td', '', ''+this.numWords);
    	body.appendChild(this.title_el);
        body.appendChild(this.level_el);
        body.appendChild(this.num_paras_el);
        body.appendChild(this.num_words_el);
    },
    refreshDocInfo: function() {
        this.title_el.innerHTML = this.Title;
        this.level_el.innerHTML = this.Level;
        this.num_paras_el.innerHTML = '' + this.numParas;
        this.num_words_el.innerHTML = '' + this.numWords;
    },
    show: function(show) {
    	this.refreshDocInfo();
        yud.setStyle(this.body, 'display', ((show)?'':'none'));
    }
};

LLDL.Bean.FlaxActivity = function(obj) {
    this.name = obj.name;
    this.title = obj.title;
    this.description = obj.description;
    this.color_theme = obj.color_theme;
};    

    /** @param flax_activity_xml - web/WEB-INF/classes/flax/<lang>/activity.xml
    *   @return HashMap - activity_name -> LLDL.Bean.FlaxActivity object
    */ 
LLDL.Bean.FlaxActivityMap = function(flax_activity_xml) {
        var map = new HashMap();
        var aname, title, description, image_url, colorTheme;
        var node_list = flax_activity_xml.getElementsByTagName('activity');
        for(var node, i=0; i<node_list.length; i++) {
            node = node_list[i];
            aname = node.getAttribute("name");
            colorTheme = node.getAttribute("colorTheme");
            var title_el = LLDL.getDomFirstChildTextNodeValue(node, 'title');
            title = (title_el)? title_el : aname; 

            var coll_des_list = node.getElementsByTagName('paragraph');
            var coll_des = [];
            for(var k=0; k<coll_des_list.length; k++) {
            	coll_des.push('<p>'+coll_des_list[k].firstChild.nodeValue+'</p>');
            }
            var info = node.getElementsByTagName('info')[0];
			var item_list = info.getElementsByTagName('item');
			for(var m=0; m<item_list.length; m++) {
				coll_des.push("<p><span class='bold'>"+
				LLDL.getDomFirstChildTextNodeValue(item_list[m], 'name')+
				"</span>: <span>"+
				LLDL.getDomFirstChildTextNodeValue(item_list[m], 'value')+
				"</span></p>");
				
			}
            
            map.put(aname, new LLDL.Bean.FlaxActivity({name:aname, title:title, color_theme:colorTheme,description:coll_des.join('')}));
        }
        return map;
    
};
/**
 * Class used by DesignActivityModule.js and SelectCollectionResource.js for listing collections
 * */
LLDL.Bean.FlaxCollectionModule = function(config, obj) {
    this.config_info = config;
    this.name = obj.name;
    this.creator = obj.creator;
    this.title = obj.title;
    this.description = obj.description;
    this.category = obj.category;
    this.numDocs = obj.numDocs;
    this.css_class = obj.css_class;
    this.default_activity = obj.cfg_activity_arr[0];
    this.cfg_activity_map = this.getCFGActivityMap(obj.cfg_activity_arr);
    this.module_coll_about_page_url = this.config_info.flax_server_domain + '/' + 
                               'flax?a=fp&sa=collAbout' +
                               '&c=' + this.name + 
                               '&if=mdl' +
                               '&mdlmodulename=' + this.config_info.mdlmodulename;
};
LLDL.Bean.FlaxCollectionModule.prototype = {
    getCollectionBody: function(container, checked) {
        var check = '';
        if(checked) {
          check = "checked";
        }
    	var body = LLDL.createEl('div','','','module_coll_title cursor_arrow');
        container.appendChild(body);
        var radio_btn_html = '<input class="collection_body" type="radio" name="collection" value="'+this.name+'" '+ check + '/>';
/** The following radio buttons are not IE friendly!
        var body = LLDL.createEl('input','', '', 'collection_body');
        body.setAttribute('type', 'radio');
        body.setAttribute('name', 'collection');
        body.setAttribute('value', this.name);
        if(checked) {
            body.setAttribute('checked', checked);
        }
*/
    	body.appendChild(LLDL.createInnerHTML('span','',radio_btn_html));
        body.appendChild(LLDL.createEl('span', this.name, this.title));
        body.appendChild(LLDL.createEl('br'));
    },
    getActivityBody: function(container) {
        var cfg = [];
        var act_arr = this.cfg_activity_map.valSet();
        for(var act, checked, i=0; i<act_arr.length; i++) {
            act = act_arr[i];
            checked = (i===0)? true : false;
            cfg.push({name:'activity', value:act.name, title:act.title, checked:checked, newline:true});
        }
        var activity_body = LLDL.createEl('div', '', '', this.css_class+' '+'activity_block');
        var activity_label = LLDL.createInnerHTML('div', '', 'Activities available for the chosen collection', 'block_label');
        activity_body.appendChild(activity_label);
        container.appendChild(activity_body);
        var body = new UI.RadioButton(activity_body, cfg);
    },
    getCFGActivityMap: function(arr) {
        var map = new HashMap();
        var act_name;
        for(var i=0; i<arr.length; i++) {
            act_name = arr[i];
            map.put(act_name, (this.config_info.all_activity_map).get(act_name));
        }
        return map;
    },
    getSummaryInnerHTML: function() {
        return "<div>"+this.description+"</div>" +
            "<div><div class='tooltip_label'>Collection creator:</div><span>"+this.creator+"</span><br/>" +
            "<div class='tooltip_label'>Number of documents:</div><span>"+this.numDocs+"</span></div>";
    }}
/**
 * used by DesignActivityModule.js and SelectCollectionResource.js for listing collections
 * */
LLDL.Bean.moduleQueryCollectionList = function(cfg) {
	var config_info = cfg.config_info;
    var data = 's;;DesignActivityModule]]service;;'+LLDL.services.DESIGN_INTERFACE+']]lang;;en]]site;;flax' +
    		   ']]mdlsiteid;;'+config_info.mdlsiteid+']]mdlusername;;'+config_info.mdlusername;
    var obj = {caller_obj: window,
               callback_fn: LLDL.Bean.moduleQueryCollectionListCallback,
               http_method: 'POST',
               url: config_info.ajax_server_url,
               err_msg: 'Error occurred when queryCollectionList in DeisgnActivityModule.js',
               passover_obj: cfg,
               postdata: data,
               show_loading_panel: true,
               loading_img_url: config_info.images_url+'blocking_loading.gif'};
    LLDL.talk2server(obj);
};     
/**
 * used by DesignActivityModule.js and SelectCollectionResource.js for listing collections
 * */
LLDL.Bean.moduleQueryCollectionListCallback = function(xml, cfg) {

    if(!xml) { window.document.write("Query collection list failed in DesignActivityModule.js."); return false; }
    var config_info = cfg.config_info;
    var activity_xml = xml.getElementsByTagName('flaxActivityList')[0];//contains descriptions of all activity types

    if(!(activity_xml)) { window.document.write("Query flaxActivityList failed in DesignActivityModule.js"); return false; } 
    var all_activity_map = new LLDL.Bean.FlaxActivityMap(activity_xml);
    config_info.all_activity_map = all_activity_map;//set it into config_info so as to pass to BuildCollection.js

    var colllist = xml.getElementsByTagName('CollectionList')[0];
    config_info.flax_server_domain = colllist.getAttribute('flax_server_domain');
    config_info.site_name = colllist.getAttribute('site_name');
    
    var colls = colllist.getElementsByTagName('collection');
    var len = colls.length;
    if(len < 1) {
        alert("\n ______________________________________\nThere are no collections on the server.\n_________________________________");
        window.close();
        return;
    }
    this.block_css_class = {flaxcoll:'spanishBox', sharecoll:'italianBox', personalcoll:'frenchBox'};
    var cfg_activity_arr = [];
    var cname = '', title = '', description = '', creator = '', category='', numDocs = '';
    for(var coll=null,i=0; i<len; i++) {
        coll = colls[i];
        cname = coll.getAttribute("name");
        creator = coll.getAttribute("creator");
        category = coll.getAttribute("category");
        numDocs = coll.getAttribute('numDocs');
        title = LLDL.getDomFirstChildTextNodeValue(coll, 'title');
        title = (title)? title: cname;              
        
        description = LLDL.getDomFirstChildTextNodeValue(coll, 'description');
        description = (description)?description: 'No description for collection: ' + cname; 
        var cfg_acts = coll.getAttribute('activity');
        if(!cfg_acts || cfg_acts.length<1) {
            continue;
        } else {
            cfg_activity_arr = cfg_acts.split(',');
        }                
        //FlaxCollectionModule is defined in BeanObjects.js
        cfg.collection_map.put(cname, new LLDL.Bean.FlaxCollectionModule(config_info, {name:cname, 
                                                                                       creator:creator, 
                                                                                       category:category,
                                                                                       numDocs: numDocs,
                                                                                       css_class:'',//this.block_css_class[category], 
                                                                                       title:title, 
                                                                                       description:description, 
                                                                                       cfg_activity_arr:cfg_activity_arr}));
    }           
    LLDL.Bean.composeCollectionList(cfg);
    
};
LLDL.Bean.composeCollectionList = function(cfg){
	var body = cfg.body;
	var coll_map = cfg.collection_map;
    var coll_list_body = LLDL.createEl('div', '','', 'section');
    coll_list_body.appendChild(LLDL.createEl('div', '', lbb.choosecoll, 'section_header'));
    body.appendChild(coll_list_body);
    
    var block_label = null;
        // FLAX distributed collections
        var flax_coll_block = LLDL.createEl('div', '','', 'spanishBox');
        block_label = LLDL.createEl('div', '', lbb.label_c0, 'block_label');;
        flax_coll_block.appendChild(block_label);
        coll_list_body.appendChild(flax_coll_block);
    
        // Collections shared within institution
        var share_coll_block = LLDL.createEl('div', '','', 'italianBox');
        block_label = LLDL.createEl('div', '', lbb.label_c1, 'block_label');
        share_coll_block.appendChild(block_label);
        coll_list_body.appendChild(share_coll_block);
    
        // Personal public collections
        var personal_coll_block = LLDL.createEl('div', '','', 'frenchBox');
        block_label = LLDL.createEl('div', '', lbb.label_c2_mdl, 'block_label');
        personal_coll_block.appendChild(block_label);
        coll_list_body.appendChild(personal_coll_block);
        
    var blocks = {};
    blocks[lbb.c0] = flax_coll_block;
    blocks[lbb.c1] = share_coll_block;
    blocks[lbb.c2] = personal_coll_block;
    var count_colls = {};
    count_colls[lbb.c0] = 0;
    count_colls[lbb.c1] = 0;
    count_colls[lbb.c2] = 0;
    
    var coll_arr = coll_map.valSet();
    var default_coll = null;
    for(var coll=null, cate, i=0; i<coll_arr.length; i++) {
        coll = coll_arr[i];
        cate = coll.category;
        count_colls[cate]++;
        if(default_coll === null && cate === lbb.c0) {
        	default_coll = coll;//display activity block of this default collection
        	default_coll.getCollectionBody(blocks[cate], true);
        } else {
            coll.getCollectionBody(blocks[cate], false);
        }
    }
    for(var p in count_colls) {
    	if(count_colls[p] === 0) {
    		blocks[p].appendChild(LLDL.createEl('div','','(none)','nonecoll'));
    	}
    }	
    //enableCollectionSummaryTooltip
	var coll_name_arr = cfg.collection_map.keySet().slice();
    var hint = new YAHOO.widget.Tooltip('coll_summary_tooltip', { context:coll_name_arr, autodismissdelay: 20000 } );
    hint.element.className = 'tooltip';
    hint.contextTriggerEvent.subscribe( 
        function(type, args) { 
            var context = args[0]; 
            hint.element.innerHTML = coll_map.get(context.id).getSummaryInnerHTML();            
    }); 
    
    var o = {
    	default_coll: default_coll,
    	coll_list_body: coll_list_body
    };
    cfg.handler.call(cfg.handler_context, o);
}
    
