/*

Copyright 2008-2015 Clipperz Srl

This file is part of Clipperz, the online password manager.
For further information about its features and functionalities please
refer to http://www.clipperz.com.

* Clipperz is free software: you can redistribute it and/or modify it
  under the terms of the GNU Affero General Public License as published
  by the Free Software Foundation, either version 3 of the License, or 
  (at your option) any later version.

* Clipperz is distributed in the hope that it will be useful, but 
  WITHOUT ANY WARRANTY; without even the implied warranty of 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Affero General Public License for more details.

* You should have received a copy of the GNU Affero General Public
  License along with Clipperz. If not, see http://www.gnu.org/licenses/.

*/

"use strict";
Clipperz.Base.module('Clipperz.PM.UI.Components.ExtraFeatures.DataImport');

Clipperz.PM.UI.Components.ExtraFeatures.DataImport.InputClass = React.createClass({

	getInitialState: function() {
		return {
			'inputString': this.props.importContext.inputString(),
//			'inputString': (this.props.importContext.inputString) ? this.props.importContext.inputString : null,
//			'format': (this.props.importContext.format) ? this.props.importContext.format : null,
			//'parsedInput': (this.props.importContext.parsedInput) ? this.props.importContext.parsedInput : null,
		};
	},
/*	
	componentDidMount: function() {
		this.updateNextStatus(this.state.inputString);
	},

	//-------------------------------------------------------------------------
	
	handleNextStep: function() {
		var result;
		var jsonData;
		var parsedInput;
		
		var inputString = this.refs['input-textarea'].getDOMNode().value.trim();
//		this.props.importContext.setData(inputString);

		result = {'inputString': inputString};
/*		
		parsedInput = this.parseJson(inputString);
		if (parsedInput) {
			MochiKit.Base.update(result, this.props.importContext.getInitialJsonContext(parsedInput));
		} else {
			parsedInput = this.parseCsv(inputString);
			if (parsedInput) {
				MochiKit.Base.update(result, this.props.importContext.getInitialCsvContext(parsedInput));
			} else {
				result = false;
			}
		}
* /		
		return result;
	},
	
	updateNextStatus: function(newInputString) {
//		this.props.setNextStepCallback((newInputString) ? this.handleNextStep : null);
	},
	
	//=========================================================================
	
	extractJsonFromClipperzExport: function(someHtml) {
		var textarea;
		var regexMatch;
		var result;
		
		var re = new RegExp('.*<textarea>(.*)<\/textarea>.*','g');
		
		if (re.test(someHtml)) {
			textarea =  this.refs['input-textarea'].getDOMNode();
			textarea.innerHTML = someHtml.replace(re, '$1');
			result = textarea.innerHTML;
		} else {
			result = false;
		}

		return result;
	},
	
	addImportIds: function (someJson) {
		var count;
		
		for (count=0; count < someJson.length; count++) {
			someJson[count]['_importId'] = count;
		}
	},
	
	parseJson: function(aJsonString) {
		var result;
		var jsonData;
		
		try {
			jsonData = JSON.parse(aJsonString);
			this.addImportIds(jsonData);
			result = jsonData;
		} catch(e) {
			result = false;
		}
		
		return result;
	},
	
	parseCsv: function(aCsvString) {
		var result;
		var i;
	
		var parsedCsv = Papa.parse(aCsvString);
		
		if (parsedCsv.errors.length != 0) {
			result = false;
		} else {
			result = this.csvFillEmptyCells(parsedCsv.data);
		}

		return result;
	},

	csvFillEmptyCells: function(table) {
		var i,j;
		
		var result = [];
		
		var maxColumns = MochiKit.Iter.reduce(function(prev,next) {
			return Math.max(prev,next)
		}, MochiKit.Base.map(function(row) {return row.length;}, table) );
		
		for (i=0; i<table.length; i++) {
			
			result[i] = [];
			for (j=0; j<maxColumns; j++) {
				result[i][j] = (typeof(table[i][j]) != "undefined") ? table[i][j] : "";
			}
		}
		
		return result;
	},
*/
	//=========================================================================

	updateTextAreaContent: function (aValue, shouldMoveForwardToo) {
		var	value;
		value = this.props.importContext.setInputString(aValue, shouldMoveForwardToo);
		this.setState({'inputString': value});
	},

	handleUploadFiles: function (someFiles) {
		var file;
		var reader;
		
		if (someFiles.length == 1) {
			file = someFiles[0];
			reader = new FileReader();
			
			// Binary files are just thrown in the textarea as weird UTF-8 characters: should we do something about it?
			reader.onloadend = MochiKit.Base.bind(function() {
/*
				var	extractedJson = this.extractJsonFromClipperzExport(reader.result);
				var newInputString;
				
				if (extractedJson) {
					newInputString = extractedJson;
				} else {
					newInputString = reader.result;
				}

				this.setState({'inputString': newInputString});
				this.updateNextStatus(newInputString);
*/
//console.log("handleUploadFiles", this.props.importContext, this.state, this);
//				this.props.importContext.setInputString(reader.result);
				this.updateTextAreaContent(reader.result, true);
			}, this);
			
			reader.readAsText(file);
		} else {
			// Should this be removed?
			alert("Error: expecting a file as input.");
		}
	},
	
	handleOnDrop: function (anEvent) {
		anEvent.preventDefault();
		
		this.handleUploadFiles(anEvent.dataTransfer.files)
	},
	
	handleInputFiles: function (anEvent) {
		anEvent.preventDefault();
		
		this.handleUploadFiles(anEvent.target.files)
	},
	
	handleOnDragOver: function (anEvent) {
		// Somehow necessary:
		// http://enome.github.io/javascript/2014/03/24/drag-and-drop-with-react-js.html
		// https://code.google.com/p/chromium/issues/detail?id=168387
		// http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html
		anEvent.preventDefault();
	},
	
	handleTextareaChange: function () {
//		var newInputString;
//		
//		newInputString = this.refs['input-textarea'].getDOMNode().value;
//		this.setState({'inputString': newInputString});
//		this.props.importContext.setInputString(newInputString);

		this.updateTextAreaContent(this.refs['input-textarea'].getDOMNode().value, false);
	},

	//=========================================================================
	
	render: function() {
		return React.DOM.div({},[
			React.DOM.div({'className':'description'}, [
				React.DOM.p({}, "Import data from a CSV file (like those produced by most password managers) or copy data from another Clipperz account using a JSON/HTML export file created by Clipperz."),
			]),
			React.DOM.form({'key':'form', 'className':'importForm' }, [
				React.DOM.input({
					'type': 'file',
					'ref': 'upload-input',
					'onClick': function(e) { e.target.value = null },
					'onChange': this.handleInputFiles,
					'style': {'display': 'none'}
				}),
				React.DOM.div({
					'onDragOver': this.handleOnDragOver,
					'onDrop': this.handleOnDrop,
					'className': 'dropArea'
				}, [
					React.DOM.span({}, "Drag your CSV or Clipperz export file here"),
					React.DOM.br({}),
					React.DOM.span({}, "or"),
					React.DOM.br({}),
					React.DOM.a({
						'className': 'button',
						'onClick': MochiKit.Base.bind(function() { this.refs['upload-input'].getDOMNode().click() }, this),
					}, "select it manually")
				]),
				React.DOM.div({'className': 'description'},
					React.DOM.p({}, "Alternatively you may type or paste any properly formatted CSV or JSON data.")
				),
				React.DOM.div({'key':'fields'},[
					React.DOM.textarea({
						'key':'input-textarea',
						'name':'input-textarea',
						'ref':'input-textarea',
						'placeholder':"Type or copy your data here",
						'value': this.state.inputString,
						'onChange': this.handleTextareaChange,
						'onDragOver': this.handleOnDragOver,
						'onDrop': this.handleOnDrop,
					}),
				])
			])
		]);
	}

});

Clipperz.PM.UI.Components.ExtraFeatures.DataImport.Input = React.createFactory(Clipperz.PM.UI.Components.ExtraFeatures.DataImport.InputClass);