package com.cwport.sentencer.data;
import android.content.Context;
import android.util.Log;
import com.cwport.sentencer.model.Card;
import com.cwport.sentencer.model.Lesson;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import au.com.bytecode.opencsv.CSVReader;
/**
* Created by isayev on 02.02.14.
*/
public class AssetDataProvider implements DataProvider {
public static final String TAG = AssetDataProvider.class.getSimpleName();
public static final String DEFAULT_LESSON_FOLDER = "lessons";
public static final String DEFAULT_LESSON_INDEX_FILE = "index";
public static final String ERROR_CANNOT_READ_INDEX = "Cannot read index file from assets.";
public static final String ERROR_LESSON_NOT_EXIST = "Lesson does not exist.";
public static final String ERROR_CANNOT_READ_LESSON_FILE = "Cannot read lesson file from assets.";
private String lessonFolder = DEFAULT_LESSON_FOLDER;
private String lessonIndex = DEFAULT_LESSON_INDEX_FILE;
private ArrayList<Lesson> lessons = new ArrayList<Lesson>();
private String[] lessonTitles = new String[]{};
private Context context;
public AssetDataProvider() {}
@Override
public void setContext(android.content.Context appContext) {
this.context = appContext;
}
@Override
public ArrayList<Lesson> getLessons() throws DataException {
readLessonIndex();
return lessons;
}
@Override
public Lesson getLesson(String id) throws DataException {
Lesson lesson = new Lesson();
for(Lesson l : lessons) {
if(id.equals(l.getId())) {
lesson = l;
break;
}
}
if(id.equals(lesson.getId())) {
String data = getLessonData(lesson.getFilename());
lesson.setCards(parseLessonData(data));
} else {
throw new DataException(ERROR_LESSON_NOT_EXIST);
}
return lesson;
}
private void readLessonIndex() throws DataException {
String lessonData = "";
InputStream stream = null;
lessons = new ArrayList<Lesson>();
try {
stream = context.getAssets().open(lessonFolder + "/" + lessonIndex);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
lessonData = new String(buffer);
if(stream != null) { stream.close(); }
} catch (IOException e) {
Log.e(TAG, e.getMessage());
throw new DataException(ERROR_CANNOT_READ_INDEX, e);
}
try {
stream = new ByteArrayInputStream(lessonData.getBytes("UTF-8"));
// read csv data from lesson index file skipping 1st line
CSVReader reader = new CSVReader(new InputStreamReader(stream), ';', '\"', 1);
String [] nextLine;
if(lessons != null) {
lessons.clear();
} else {
lessons = new ArrayList<Lesson>();
}
while ((nextLine = reader.readNext()) != null) {
Lesson lesson = new Lesson(nextLine[0], nextLine[1], nextLine[2],
nextLine[3], nextLine[4], Integer.parseInt(nextLine[5]));
lesson.setSourceType(SourceType.ASSET);
lesson.setId(DataHelper.md5(lesson.getFilename() + lesson.getCardCount()));
lessons.add(lesson);
}
reader.close();
stream.close();
} catch(UnsupportedEncodingException ex) {
Log.e(TAG, ex.getMessage());
throw new DataException(ERROR_CANNOT_READ_INDEX, ex);
} catch(Exception e) {
Log.e(TAG, e.getMessage());
throw new DataException(ERROR_CANNOT_READ_INDEX, e);
}
}
private String getLessonData(String lessonFile) throws DataException {
String lessonData = "";
InputStream stream = null;
Log.d(TAG, "Parse file: " + lessonFile);
try {
stream = context.getAssets().open(lessonFolder + "/" + lessonFile);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
// stream.close();
lessonData = new String(buffer);
if(stream != null) { stream.close(); }
} catch (IOException e) {
Log.e(TAG, e.getMessage());
throw new DataException(ERROR_CANNOT_READ_LESSON_FILE, e);
}
return lessonData;
}
private ArrayList<Card> parseLessonData(String csv) throws DataException {
ArrayList<Card> cards = new ArrayList<Card>();
int line = 0;
try {
InputStream stream = new ByteArrayInputStream(csv.getBytes("UTF-8"));
CSVReader reader = new CSVReader(new InputStreamReader(stream), ';', '\"', 0);
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
String faceText = nextLine[0].trim();
String backText = nextLine[1].trim();
Card c = new Card(DataHelper.md5(faceText), faceText, backText, false);
cards.add(c);
line++;
}
reader.close();
stream.close();
} catch(UnsupportedEncodingException ex) {
Log.e(TAG, "Line:" + line + "; Error: " + ex.getMessage());
throw new DataException(ERROR_CANNOT_READ_LESSON_FILE, ex);
} catch(Exception e) {
Log.e(TAG, "Line:" + line + "; Error: " + e.getMessage());
throw new DataException(ERROR_CANNOT_READ_LESSON_FILE + "at line " + line, e);
}
return cards;
}
}