/**
 * @class Voyeur.Tool.DocumentInputAdd A panel that provides widgets for creating and updating a corpus.
 * @extends_ext Ext.Panel
 * @extends Voyeur.Tool
 * @namespace Voyeur.Tool
 * @author Stéfan Sinclair
 * @since 0.1.1
 */
Voyeur.Tool.DocumentInputAdd = Ext.extend(Ext.Panel, {
	constructor : function(config) {
	
		Ext.apply(this, new Voyeur.Tool(config, this));

		var xtype = config.xtype;
		Ext.applyIf(config, {
			bodyStyle: 'text-align: center;',
			items: [{
				xtype: 'textarea',
				id: 'input',
				name: 'input',
				cls: 'input_box',
				hideLabel: true,
				width:'100%'
				,emptyText: this.localize('input_label')
			}, {
				xtype: 'button',
				id: 'reveal',
				text: this.localize('reveal'),
				handler: function(btn){
					var input_value = Ext.getCmp('input').getValue().replace(/^\s+/, '');
					if (this.getCorpus().isEmpty() && input_value.length == 0) {
						return this.alertError({
							msg: this.localize('empty_input_error')
							,animEl: btn.id
							,fn: function(){
								var el = Ext.getCmp('input').getEl();
								el.frame("ff0000");
							}
						});
					}
					var params = this.getApiParams(true);
					params.input = input_value;
					params.corpusCreateIfNotExists = true;
					this.update({
						tool : 'CorpusSummary'
						,params: params
					})
				},
				scope: this
			}]
			,bbar: [{
				xtype: 'tbbutton'
				,text: this.localize('upload')
				,tooltip : this.localize('uploadTip')
				,iconCls: 'tbupload'
				,handler : function(b, e) {
					if (Ext.getCmp('input').getValue()) {
						Ext.Msg.show({
							title : this.localize('uploadIgnoresInputTitle')
							,msg : this.localize('uploadIgnoresInputMsg')
							,buttons : Ext.Msg.YESNO
							,icon: Ext.MessageBox.QUESTION
							,fn: function(btn) {
								if (btn=='yes') {this.showFileUpload(b.el);}
							}
							,scope: this
						})
					}
					else {this.showFileUpload(b.el);}
				}
				,scope : this
			},
			{
				xtype: 'tbbutton'
				,text: this.localize('openCorpus')
				,tooltip : this.localize('openCorpusTip')
				,iconCls: 'icon-folder'
				,handler : function(b, e) {
					if (Ext.getCmp('input').getValue()) {
						Ext.Msg.show({
							title : this.localize('openCorpusIgnoresInputTitle')
							,msg : this.localize('openCorpusIgnoresInputMsg')
							,buttons : Ext.Msg.YESNO
							,icon: Ext.MessageBox.QUESTION
							,fn: function(btn) {
								if (btn=='yes') {this.showOpenCorpus(b.el);}
							}
							,scope: this
						})
					}
					else {this.showOpenCorpus(b.el);}
				}
				,scope : this
			}]
		});
		Voyeur.Tool.DocumentInputAdd.superclass.constructor.apply(this, arguments);
		
	}

	,showOpenCorpus : function(btnEl) {
		var win = new Ext.Window({
			modal: true
			,title: this.localize('openCorpus')
			,width: 400
			,items: [{
    				xtype : 'form',
    				labelWidth : 50,
    				labelAlign : 'right',
    				padding: '5px 0 0 0',
    				border : false,
    				items : [{
    					xtype : 'combo',
    					id : 'comparisonCorpus',
//    					value : this.getStore().baseParams.comparisonCorpus,
    					fieldLabel : '<span ext:qtip="'
    							+ this.localize('openCorpusTip') + '">'
    							+ this.localize('openCorpus') + '</span>',
    					loadingText : this.localize('loading', 'tool'),
    					width : 300,
    					store : this.getApplication().getCorporaStore()
    				    ,mode:'local'
    				    ,selectOnFocus : true
    				    ,displayField: 'label'
    				    ,triggerAction: 'all'
    				    ,valueField: 'id'
    				    ,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 comparisonCorpus = form.findField('comparisonCorpus');

									// make sure we don't have any queries
									if (comparisonCorpus.getValue() && !comparisonCorpus.getRawValue()) {comparisonCorpus.setValue('');}
									else if (comparisonCorpus.lastQuery && comparisonCorpus.lastQuery!=comparisonCorpus.getValue()) {
										comparisonCorpus.getStore().loadData({corpora: {corpora: [{id: comparisonCorpus.lastQuery, label: comparisonCorpus.lastQuery, description: ''}]}}, true);
										comparisonCorpus.setValue(comparisonCorpus.lastQuery)
									}
			
									if (form.isDirty()) {
										this.update({params: {corpus: comparisonCorpus.getValue()}, tool: 'CorpusSummary'})
									}
									formPanel.findParentByType('window').close();
						
    							},
    							scope : this
    						}
    					}
    				},{
    					text : this.localize('cancel', 'tool'),
    					handler : function(btn) {
    						btn.findParentByType('window').close();
    					}
    				}]
     			}
			]
		});
		win.show(btnEl);
	}
	
	/**
	 * Show the file upload panel.
	 */
	,showFileUpload : function(btnEl) {
		 var win = new Ext.Window({
		 width:180
		 ,minWidth:165
		 ,height:220
		 ,minHeight:200
		 ,stateful:true
		 ,modal:true
		 ,layout:'fit'
		 ,border:false
		 ,closable:true
		 ,title:this.localize('upload')
		 ,items:[{
			xtype:'uploadpanel'
			,addText:this.localize('fileAdd')
			,clickRemoveText : this.localize('clickRemoveText')
			,clickStopText : this.localize('clickStopText')
			,emptyText : this.localize('emptyText')
			,errorText : this.localize('errorText')
			,fileQueuedText : this.localize('fileQueuedText')
			,fileDoneText : this.localize('fileDoneText')
			,fileFailedText : this.localize('fileFailedText')
			,fileStoppedText : this.localize('fileStoppedText')
			,fileUploadingText : this.localize('fileUploadingText')
			,removeAllText : this.localize('removeAllText')
			,removeText : this.localize('removeText')
			,stopAllText : this.localize('stopAllText')
			,uploadText : this.localize('upload')
			,buttonsAt:'tbar'
			,id:'uppanel'
			,url:this.getTromboneUrl()
			,path:'root'
			,maxFileSize:1048576
			,enableProgress:false
			,singleUpload:true
			,forTool: this
			,listeners: {
				'render': {
					fn: function(panel) {
						
						// we need to set the corpus before uploading so that all files are added to the same corpus
						panel.uploader.baseParams = this.getApiParams();
						panel.uploader.baseParams.corpusCreateIfNotExists = true;

						// we'll handle the results ourselves because we want different parsing of results and behaviour
						panel.uploader.uploadCallback = function(options, success, response) {
							var uploader = panel.uploader;
							uploader.upCount--;
							uploader.form = false;
							var r = response.responseText;
							// for some reason FF wraps the response in <pre> tag
							r = r.replace(/<\/?pre.*?>/g,'');
							r = Ext.decode(r);
							if (r.error) {
								uploader.processFailure(options, response, r.error);
							}
							else {
								uploader.processSuccess(options, response, r);
								if (uploader.upCount==0) { // all finished
									/**
									 * @event CorpusSummaryResultLoaded
									 * @param {Voyeur.Tool.DocumentInputAdd} tool
									 * @param {Object} response
									 * @type dispatcher
									 */
									panel.forTool.getApplication().dispatchEvent('CorpusSummaryResultLoaded', panel.forTool, r);
									panel.ownerCt.destroy();
								}
							}
							uploader.fireFinishEvents(options);
						}
					}
					,scope: this
				}
			}
		 }]
		 });
		 win.show(btnEl);
	}

	,showOptions : function() {
		this.showOptionsWindow({
			items : [{
				xtype : 'form',
				labelWidth : 150,
				labelAlign : 'right',
				border : false,
				items : [{
						xtype: 'combo',
						name: 'inputFormat',
					    store: new Ext.data.ArrayStore({
					        id: 0,
					        fields: [
					            'value',
					            'displayText'
					        ],
					        data: [['XML'], ['RSS2']]
					    }),
					    displayField:'value',
					    valueField: 'value',
					    mode: 'local',
					    value: this.getApiParamValue('inputFormat'),
//					    triggerAction: 'all',
					    emptyText: this.localize('emptyInputFormat'),
					    editable: false,
					    fieldLabel: '<span ext:qtip="'
							+ this.localize('inputFormatTip') + '">'
							+ this.localize('inputFormat') + '</span>'
					},{
    				xtype: 'fieldset',
                    title: 'XML Options',
                    collapsible: true,
                    items: [
						{
						    xtype     : 'textfield',
						    name      : 'xmlContentXpath',
						    value	  : this.getApiParamValue('xmlContentXpath'),
						    fieldLabel: '<span ext:qtip="'
    							+ this.localize('xmlContentXpathTip') + '">'
    							+ this.localize('xmlContentXpath') + '</span>'
						},{
						    xtype     : 'textfield',
						    name      : 'xmlAuthorXpath',
						    value	  : this.getApiParamValue('xmlAuthorXpath'),
						    fieldLabel: '<span ext:qtip="'
    							+ this.localize('xmlAuthorXpathTip') + '">'
    							+ this.localize('xmlAuthorXpath') + '</span>'
						},{
						    xtype     : 'textfield',
						    name      : 'xmlTitleXpath',
						    value	  : this.getApiParamValue('xmlTitleXpath'),
						    fieldLabel: '<span ext:qtip="'
    							+ this.localize('xmlTitleXpathTip') + '">'
    							+ this.localize('xmlTitleXpath') + '</span>'
						},{
						    xtype     : 'textfield',
						    name      : 'xmlDocumentsXpath',
						    value	  : this.getApiParamValue('xmlDocumentsXpath'),
						    fieldLabel: '<span ext:qtip="'
    							+ this.localize('xmlDocumentsXpathTip') + '">'
    							+ this.localize('xmlDocumentsXpath') + '</span>'
						}
    				]}],
				buttons : [{
					text : this.localize('ok', 'tool'),
					iconCls : 'icon-accept',
					listeners : {
						click : {
							fn : function(btn) {
								var formPanel = btn.findParentByType('form');
								var form = formPanel.getForm();
								var inputFormat = form.findField('inputFormat');
								var xmlContentXpath = form.findField('xmlContentXpath');
								var xmlAuthorXpath = form.findField('xmlAuthorXpath');
								var xmlTitleXpath = form.findField('xmlTitleXpath');
								var xmlDocumentsXpath = form.findField('xmlDocumentsXpath');
								this.setApiParams({
									inputFormat: inputFormat.getValue(),
									xmlContentXpath: xmlContentXpath.getValue(),
									xmlAuthorXpath: xmlAuthorXpath.getValue(),
									xmlTitleXpath: xmlTitleXpath.getValue(),
									xmlDocumentsXpath: xmlDocumentsXpath.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('inputFormat').setValue(this.getApiParamDefaultValue('inputFormat'));
								form.findField('xmlContentXpath').setValue(this.getApiParamDefaultValue('xmlContentXpath'));
								form.findField('xmlAuthorXpath').setValue(this.getApiParamDefaultValue('xmlAuthorXpath'));
								form.findField('xmlTitleXpath').setValue(this.getApiParamDefaultValue('xmlTitleXpath'));
								form.findField('xmlDocumentsXpath').setValue(this.getApiParamDefaultValue('xmlDocumentsXpath'))
							},
							scope : this
						}
					}
	
				}]
			}]
		})

	}
	
	,api: {
		/**
		 * @property inputFormat The format of the corpus to import.  Supported formats are XML and RSS2.
		 * @type String
		 * @default null
		 * @choices TEXT, HTML, XML, RSS2, OLDBAILEY, ZIP, TAR, MSWORD, MSWORDX, PDF, RTF
		 */
		'inputFormat': {
			'default': null,
			'choices': ['XML', 'RSS2']
		}
		/**
		 * @property xmlContentPath An XPath for locating the corpus content.
		 * @type String
		 * @default null
		 */
		,'xmlContentXpath': {'default': null}
		/**
		 * @property xmlAuthorXpath An XPath for locating the corpus author.
		 * @type String
		 * @default null
		 */
		,'xmlAuthorXpath': {'default': null}
		/**
		 * @property xmlTitleXpath An XPath for locating the corpus title.
		 * @type String
		 * @default null
		 */
		,'xmlTitleXpath': {'default': null}
		/**
		 * @property xmlDocumentsXpath An XPath for locating the corpus documents.
		 * @type String
		 * @default null
		 */
		,'xmlDocumentsXpath': {'default': null}
		,toolType: ['Document']
		,dispatchers: ['CorpusSummaryResultLoaded']
	}
	
	,thumb: {
		large: 'DocumentInputAdd.png'
	}
	
	// private localization variables
	,i18n : {
		title : {en: "Add Texts"}
		,input_label : {en: "Type in one ore more URLs on separate lines or paste in a full text."}
		,reveal : {en: "reveal"}
		,inputFormat: {en: 'Input Format'}
		,inputFormatTip: {en: 'Defines the input format. In most cases the format can be reliably guessed (by filename or content type). However, in some cases the format needs to be specified.'}
		,emptyInputFormat: {en: 'Leave blank for auto-detect'}
		,xmlContentXpath : {en: "XPath to Content"}
		,xmlContentXpathTip : {en: "The XPath query used to specify which nodes should be used for content (by default all nodes are used). Note that this XPath is relative to each document when using split documents within one file."}
		,xmlTitleXpath : {en: "XPath to Title"}
		,xmlTitleXpathTip : {en: "The XPath query used to specify the node that contains the title of the document(s) – by default the filename is used for single documents and the start of the content is used for split documents. Note that this XPath is relative to each document when using split documents within one file."}
		,xmlAuthorXpath : {en: "XPath to Author"}
		,xmlAuthorXpathTip : {en: "The XPath query used to specify the node that contains the author of the document(s) – by default the author remains unknown. Note that this XPath is relative to each document when using split documents within one file."}
		,xmlDocumentsXpath : {en: "XPath to Documents"}
		,xmlDocumentsXpathTip : {en: "A single file can be split into multiple documents according to an XPath query defined by this option (an example would be taking an RSS feed and dividing each post into a separate document)."}
		,upload : {en: "Upload"}
		,uploadTip : {en : "Click this to upload one or more files from your local computer."}
		,uploadIgnoresInputTitle : {en: "Confirmation Required"}
		,uploadIgnoresInputMsg : {en: "You cannot upload a file <b>and</b> specify other text(s) to be added. Do you wish to continue with uploading one or more files (the contents of the <i>Add Texts</i> box will be ignored)?"}
		,openCorpus : {en: "Open"}
		,openCorpusTip : {en : "Click this to open a pre-defined corpus."}
		,openCorpusIgnoresInputTitle : {en: "Confirmation Required"}
		,openCorpusIgnoresInputMsg : {en: "You cannot open an existing corpus <b>and</b> specify other text(s) to be added. Do you wish to continue with opening a corpus (the contents of the <i>Add Texts</i> box will be ignored)?"}
		,fileAdd : {en: "Add"}
		,clickRemoveText : {en: "Click to remove"}
		,clickStopText : {en: "Click to stop"}
		,emptyText : {en: "No files"}
		,errorText : {en: "Error"}
		,fileQueuedText : {en: "File <b>{0}</b> is queued for upload"}
		,fileDoneText : {en: "File <b>{0}</b> has been successfully uploaded"}
		,fileFailedText : {en: "File <b>{0}</b> failed to upload"}
		,fileStoppedText : {en: "File <b>{0}</b> stopped by user"}
		,fileUploadingText : {en: "Uploading file <b>{0}</b>"}
		,removeAllText : {en: "Remove All"}
		,removeText : {en: "Remove"}
		,stopAllText : {en: "Stop All"}
		,empty_input_error : {en: "Please provide input before continuing."}
		,help : {en: "<p>This tool allows you to specify the origin of the texts to be analyzed.</p><p>You can provide one or more URLs (on separate lines). Each available URL will be fetched and added as a document. Supported formats include plain text (.txt), HTML (.html), XML (.xml), MS Word (.doc, .docx), RTF (.rtf), and PDF (.pdf).</p><p>You can also copy and paste a single text into the box (this may be preferable if you're experiencing problems with character encoding). You will be able to add additional texts later.</p>"}
	}
});

Ext.reg('voyeurDocumentInputAdd', Voyeur.Tool.DocumentInputAdd);

