/*******************************************************************************
 * Caleydo - Visualization for Molecular Biology - http://caleydo.org
 * Copyright (c) The Caleydo Team. All rights reserved.
 * Licensed under the new BSD license, available at http://caleydo.org/license
 ******************************************************************************/
package generic;

import generic.ImportSpec.ColumnSpec;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.caleydo.core.util.collection.Pair;
import org.caleydo.core.util.logging.Logger;
import org.caleydo.core.view.opengl.layout2.GLSandBox;
import org.caleydo.vis.rank.model.ARankColumnModel;
import org.caleydo.vis.rank.model.RankRankColumnModel;
import org.caleydo.vis.rank.model.RankTableModel;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;

import demo.RankTableDemo;
import demo.RankTableDemo.IModelBuilder;

/**
 * @author Samuel Gratzl
 *
 */
public class GenericModelBuilder implements IModelBuilder {
	private static final Logger log = Logger.create(GenericModelBuilder.class);
	private ImportSpec spec;

	/**
	 *
	 */
	public GenericModelBuilder() {
		this.spec = new ImportWizard().call();
	}

	@Override
	public void apply(RankTableModel table) throws Exception {
		if (spec == null)
			return;
		Pair<List<GenericRow>, String[]> r = readData();
		table.addData(r.getFirst());

		String[] headers = r.getSecond();
		table.add(new RankRankColumnModel());
		if (headers != null) {
			for (ColumnSpec col : spec.getColumns()) {
				table.add(col.create(headers));
			}
		}
	}

	/**
	 * @return
	 */
	private Pair<List<GenericRow>, String[]> readData() {
		List<ColumnSpec> cols = spec.getColumns();
		StringBuilder report = new StringBuilder();
		try (BufferedReader r = new BufferedReader(new FileReader(spec.getDataSourcePath()))) {
			String header = r.readLine();
			String[] columns = header.split(spec.getDelimiter());
			String line;
			List<GenericRow> result = new ArrayList<>();
			for(int line_i = 0; ((line = r.readLine()) != null); ++line_i) {
				String[] vals = line.split(spec.getDelimiter());
				Object[] data = new Object[spec.getColumns().size()];
				for (int i = 0; i < cols.size(); ++i) {
					try {
						data[i] = cols.get(i).parse(vals);
					} catch (NumberFormatException e) {
						log.error("can't parse: " + line_i + " col " + cols.get(i).col, e);
						report.append(line_i).append("/").append(cols.get(i).col).append(": parsing error: ")
								.append(e.getMessage()).append('\n');
						data[i] = null;
					}
				}
				result.add(new GenericRow(data));
			}
			if (report.length() > 0) {
				ErrorDialog.openError(null, "Parsing Errors", "Loading Error", new Status(IStatus.ERROR,
						"GenericModelBuilder", report.toString()));
			}
			return Pair.make(result, columns);
		} catch (IOException e) {
			ErrorDialog.openError(null, "Error during loading", "Loading Error", new Status(IStatus.ERROR,
					"GenericModelBuilder", e.getMessage(), e));
			log.error("can't parse", e);
		}
		return Pair.make(Collections.<GenericRow> emptyList(), null);
	}

	public static void main(String[] args) {
		// dump();
		GLSandBox.main(args, RankTableDemo.class, "UserStudy NASATxlResults", new GenericModelBuilder());
	}

	@Override
	public Iterable<? extends ARankColumnModel> createAutoSnapshotColumns(RankTableModel table, ARankColumnModel model) {
		Collection<ARankColumnModel> ms = new ArrayList<>(2);
		ms.add(new RankRankColumnModel());
		return ms;
	}
}

@@ -467,22 +467,16 @@
 .io.File
-Reader
 ;%0Aimport
@@ -493,24 +493,85 @@
 OException;%0A
+import java.nio.charset.Charset;%0Aimport java.nio.file.Files;%0A
 import java.
@@ -2035,20 +2035,25 @@
 der r = 
+Files.
 new
- 
 Buffered
@@ -2067,22 +2067,16 @@
 new File
-Reader
 (spec.ge
@@ -2093,16 +2093,55 @@
 ePath())
+.toPath(),%0A%09%09%09%09Charset.defaultCharset()
 )) %7B%0A%09%09%09

use UTF-8 charset