
/**
 * @class Cirrus 
 * @description A simple panel which loads the Cirrus app
 * @extends Ext.Panel
 * @extends Voyeur.Tool
 * @author Andrew MacDonald
 * @since 1.0
 */
Voyeur.Tool.Cirrus = Ext.extend(Ext.Panel, {
    initialized: false,
    flashInitialized: false,
    getCirrusObjectId : function() {return this.id.replace(/-/g,'_')+'_cirrus';}
    
    // number of terms to fetch at a time
    ,limit: 75
    
    ,initCirrus: function(params) {
        if (!this.initialized) {
        	var flashvars = {baseUrl: this.getTromboneUrl()};
        	var keys = ['background','fade','smoothness','diagonals'];
        	for (var k in keys) {
        		flashvars[keys[k]] = this.getApiParamValue(keys[k]);
        	}
            var id = this.getCirrusObjectId();
var scripts = '<script type="text/javascript">'+
'function cirrusClickHandler(word, value) {'+
'if (window.console && console.info) console.info(word, value);'+
'var cirrusTool = Ext.ComponentMgr.all.find(function(object){if (object.xtype==\'voyeurCirrus\') {return true;} else {return false;}});'+
'cirrusTool.cirrusClickHandler(word, value);'+
'}'+
'function cirrusLoaded() {'+
'if (window.console && console.info) console.info("cirrus flash loaded");'+
'var cirrusTool = Ext.ComponentMgr.all.find(function(object){if (object.xtype==\'voyeurCirrus\') {return true;} else {return false;}});'+
'cirrusTool.cirrusLoaded();'+
'}'+
'function resizeCirrus(width, height) {'+
'var flashObj = Ext.getDom("'+id+'");'+
'flashObj.setAttribute("width", width);'+
'flashObj.setAttribute("height", height);'+
'function doResize(){flashObj.resizeWords();}'+
'doResize.defer(50);'+
'}'+
'</script>';
            this.body.update(scripts+'<div id="'+id+'"></div>', true);
            var params = {
                menu: 'false',
                scale: 'showall',
                allowScriptAccess: 'always',
                bgcolor: '#222222',
                wmode: 'opaque'
            };
            var attributes = {
                id: id,
                name: id
            };
            swfobject.embedSWF(this.getApplication().getBaseUrl()+"resources/lib/cirrus/Cirrus.swf", id,
                '100%', '100%', "10.0.0", "expressInstall.swf", flashvars, params, attributes);
            this.initialized = true;
        }
    },
    
    cirrusLoaded: function() {
        this.flashInitialized = true;
    },
    
    cirrusClickHandler: function(word, value) {
        if (value == this.getCorpus().getId()) {
            Voyeur.application.dispatchEvent('corpusTypeSelected', this, {type: word});
        } else {
            var docIdType = value + ':' + word;
            Voyeur.application.dispatchEvent('documentTypesSelected', this, {docIdType: docIdType});
        }
    },
    
    constructor : function(config) {
    	
        Ext.apply(this, new Voyeur.Tool(config, this));
        
        Voyeur.Tool.Cirrus.superclass.constructor.apply(this, arguments);
        
        this.addListener('CorpusSummaryResultLoaded', function() {
			if (this.rendered) {this.fireEvent('afterrender', this);}
        }, this);
        
        this.addListener('afterrender', function(src, params) {    
			if (this.getCorpus().getSize()==0) {this.body.update('');}
			else {
				this.initCirrus(params);
	        	this.fetch(this.getApiParamValue('docId') || this.getApiParamValue('docIndex') ? 'DocumentTypeFrequencies' : 'CorpusTypeFrequencies');
			}
        }, this);

        this.addListener('corpusDocumentSelected', function(src, params) {
        	this.setApiParams(params);
        	this.fetch('CorpusTypeFrequencies');
        }, this);
    	this.addListener('CorpusTypeFrequenciesResultLoaded', function(src, data) {
    		this.handleTypeData(this.corpusTypeReader.readRecords(data).records,'corpus');
    	}, this);
    	this.addListener('DocumentTypeFrequenciesResultLoaded', function(src, data) {
    		this.handleTypeData(this.documentTypeReader.readRecords(data).records,'document');
    	}, this);
        
    }
    
    ,handleTypeData : function (records, mode) {
        var words = [];
        var freqField = mode=='corpus' ? 'rawFreq' : 'relativeFreq';
        for (var i = 0; i < records.length; i++) {
            var word = {word: records[i].get('type'), size: records[i].get(freqField), label: records[i].get(freqField)};
            if (mode =='corpus') word.value = this.getCorpus().getId();
            else word.value = records[i].get('docId');
            words.push(word);
        }
        this.sendWords(words);
    }

    ,clearAll: function() {
        var id = this.getCirrusObjectId();
        var cirrusApp = Ext.getDom(id);
        cirrusApp.clearAll();
    }
    
    ,sendWords: function(words) {
		var me = this;
		try {
            var id = this.getCirrusObjectId();
            var cirrusApp = Ext.getDom(id);
            var doResize = cirrusApp.addWords(words);
            if (doResize) cirrusApp.resizeWords();
            cirrusApp.arrangeWords();
		}
		catch (e) {
			setTimeout(function(){me.sendWords.call(me,words)},750)
		}
    }
    
    /**
     * Fetch Voyeur results using the specified tool and the provided params (and other parameters as needed).
     * @params {String} tool the tool to fetch data (CorpusTypeFrequencies or DocumentTypeFrequencies)
     * @params {Object} params parameters to be sent to the tool (others may be provided by default if not specified).
     */
    ,fetch : function(tool) {
    	this.update({tool: tool, params: this.getApiParams()});
    }
    
	,corpusTypeReader : new Ext.data.JsonReader({
		root : 'corpusTypes.types'
		,totalProperty : 'corpusTypes["@totalTypes"]'
	}, Ext.data.Record.create(Voyeur.data.CorpusTypes.fields)) 
	,documentTypeReader : new Ext.data.JsonReader({
		root : 'documentTypes.types'
		,totalProperty : 'documentTypes["@totalTypes"]'
	}, Ext.data.Record.create(Voyeur.data.DocumentTypes.fields))
	
	
	,showOptions : function() {
		this.showOptionsWindow({
			items : [{
				xtype : 'form',
				labelWidth : 150,
				labelAlign : 'right',
				border : false,
				items : [{
					xtype : 'combo',
					id : 'stopList',
					value : this.stopList,
					fieldLabel : '<span ext:qtip="'
							+ this.localize('stopListTip','tool') + '">'
							+ this.localize('stopList','tool') + '</span>',
					loadingText : this.localize('loading', 'tool'),
					width : 300,
					store : this.getApplication().getStopListsStore()
				    ,selectOnFocus : true
				    ,displayField: 'label'
				    ,triggerAction: 'all'
				    ,valueField: 'id'
				    ,mode: 'local'
				    ,emptyText: this.localize('none','tool')
				}],
				buttons : [{
					text : this.localize('ok', 'tool'),
					iconCls : 'icon-accept',
					listeners : {
						click : {
							fn : function(btn) {
								var formPanel = btn.findParentByType('form');
								var form = formPanel.getForm();
								var stopList = form.findField('stopList');
								
								// make sure we don't have any queries
								if (stopList.getValue() && !stopList.getRawValue()) {stopList.setValue('');}
								this.setApiParams({stopList: stopList.getValue()});
								
								this.initialized = false;
								this.initCirrus({});
						    	this.reupdate({stopList: stopList.getValue()});
						    	
								formPanel.findParentByType('window').destroy();
							},
							scope : this
						}
					}
				}, {
					text : this.localize('cancel', 'tool'),
					handler : function(btn) {
						btn.findParentByType('window').destroy();
					}
				}, {
					text : this.localize('restore', 'tool'),
					listeners : {
						click : {
							fn : function(btn) {
								var form = btn.findParentByType('form').getForm();
								form.findField('stopList').setValue(this.stopList);
							},
							scope : this
						}
					}
	
				}]
			}]
		})

	}
	
	,api: {
		'stopList': {
			'default': null
			,'type': String
			,'required': false
			,'value': null
			,'multiple': false
			,'choices': ['stop.en.taporware.txt', 'stop.en.glasgow.txt']
			,'example': 'stop.en.taporware.txt'
		}
		,'docIndex': {
			'default': null
			,'type': Number
			,'required': false
			,'value': null
			,'multiple': true
			,'example': 0
		}
		,'docId': {
			'default': null
			,'type': String
			,'required': false
			,'value': null
			,'multiple': true
			,'example': 'a_valid_document_id'
		}
		,'background': {
			'default': '0xffffff'
			,'type': String
			,'required': false
			,'value': null
			,'multiple': false
		}
		,'fade': {
			'default': true
			,'type': Boolean
			,'required': false
			,'value': null
			,'multiple': false
		}
		,'smoothness': {
			'default': 5
			,'type': Number
			,'required': false
			,'value': null
			,'multiple': false
		}
		,'diagonals': {
			'default': 'none'
			,'type': String
			,'required': false
			,'value': null
			,'multiple': false
		}
		,limit: {
			'default': 75
			,type: Number
		}
	}
	
    ,i18n : {
        title : {en: 'Cirrus'}
        ,help: {en: 'This tool organizes words into a "cloud".'}
        ,adaptedFrom: {en: 'This tool is based on this <a href="http://emumarketing.uoregon.edu/paul/2008/09/28/the-new-tag-cloud/" target="_blank">Wordle Clone</a>.'}
    }
});

Ext.reg('voyeurCirrus', Voyeur.Tool.Cirrus);
