package net.osmand.plus.activities;
import android.content.Context;
import android.os.Build;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import net.osmand.IndexConstants;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.voice.MediaCommandPlayerImpl;
import net.osmand.plus.voice.TTSCommandPlayerImpl;
import net.osmand.util.Algorithms;
import java.io.File;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
public class LocalIndexHelper {
private final OsmandApplication app;
public LocalIndexHelper(OsmandApplication app) {
this.app = app;
}
public String getInstalledDate(File f) {
return android.text.format.DateFormat.getMediumDateFormat(app).format(getInstalationDate(f));
}
public Date getInstalationDate(File f) {
final long t = f.lastModified();
return new Date(t);
}
public String getInstalledDate(long t, TimeZone timeZone) {
return android.text.format.DateFormat.getMediumDateFormat(app).format(new Date(t));
}
public void updateDescription(LocalIndexInfo info) {
File f = new File(info.getPathToData());
if (info.getType() == LocalIndexType.MAP_DATA) {
Map<String, String> ifns = app.getResourceManager().getIndexFileNames();
if (ifns.containsKey(info.getFileName())) {
try {
Date dt = app.getResourceManager().getDateFormat().parse(ifns.get(info.getFileName()));
info.setDescription(getInstalledDate(dt.getTime(), null));
} catch (ParseException e) {
e.printStackTrace();
}
} else {
info.setDescription(getInstalledDate(f));
}
} else if (info.getType() == LocalIndexType.TILES_DATA) {
ITileSource template;
if (f.isDirectory() && TileSourceManager.isTileSourceMetaInfoExist(f)) {
template = TileSourceManager.createTileSourceTemplate(new File(info.getPathToData()));
} else if (f.isFile() && f.getName().endsWith(SQLiteTileSource.EXT)) {
template = new SQLiteTileSource(app, f, TileSourceManager.getKnownSourceTemplates());
} else {
return;
}
String descr = "";
descr += app.getString(R.string.local_index_tile_data_name, template.getName());
if (template.getExpirationTimeMinutes() >= 0) {
descr += "\n" + app.getString(R.string.local_index_tile_data_expire, template.getExpirationTimeMinutes());
}
info.setAttachedObject(template);
info.setDescription(descr);
} else if (info.getType() == LocalIndexType.SRTM_DATA) {
info.setDescription(app.getString(R.string.download_srtm_maps));
} else if (info.getType() == LocalIndexType.WIKI_DATA) {
info.setDescription(getInstalledDate(f));
} else if (info.getType() == LocalIndexType.TTS_VOICE_DATA) {
info.setDescription(getInstalledDate(f));
} else if (info.getType() == LocalIndexType.DEACTIVATED) {
info.setDescription(getInstalledDate(f));
} else if (info.getType() == LocalIndexType.VOICE_DATA) {
info.setDescription(getInstalledDate(f));
} else if (info.getType() == LocalIndexType.FONT_DATA) {
info.setDescription(getInstalledDate(f));
}
}
private LocalIndexInfo getLocalIndexInfo(LocalIndexType type, String downloadName, boolean roadMap, boolean backuped) {
File fileDir = null;
String fileName = null;
if (type == LocalIndexType.MAP_DATA) {
if (!roadMap) {
fileDir = app.getAppPath(IndexConstants.MAPS_PATH);
fileName = Algorithms.capitalizeFirstLetterAndLowercase(downloadName)
+ IndexConstants.BINARY_MAP_INDEX_EXT;
} else {
fileDir = app.getAppPath(IndexConstants.ROADS_INDEX_DIR);
fileName = Algorithms.capitalizeFirstLetterAndLowercase(downloadName)
+ IndexConstants.BINARY_ROAD_MAP_INDEX_EXT;
}
} else if (type == LocalIndexType.SRTM_DATA) {
fileDir = app.getAppPath(IndexConstants.SRTM_INDEX_DIR);
fileName = Algorithms.capitalizeFirstLetterAndLowercase(downloadName)
+ IndexConstants.BINARY_SRTM_MAP_INDEX_EXT;
} else if (type == LocalIndexType.WIKI_DATA) {
fileDir = app.getAppPath(IndexConstants.WIKI_INDEX_DIR);
fileName = Algorithms.capitalizeFirstLetterAndLowercase(downloadName)
+ IndexConstants.BINARY_WIKI_MAP_INDEX_EXT;
}
if (backuped) {
fileDir = app.getAppPath(IndexConstants.BACKUP_INDEX_DIR);
}
if (fileDir != null && fileName != null) {
File f = new File(fileDir, fileName);
if (f.exists()) {
LocalIndexInfo info = new LocalIndexInfo(type, f, backuped, app);
updateDescription(info);
return info;
}
}
return null;
}
public LocalIndexInfo getLocalIndexInfo(String downloadName) {
LocalIndexInfo info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, false, false);
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, true, false);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.SRTM_DATA, downloadName, false, false);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.WIKI_DATA, downloadName, false, false);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, false, true);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, true, true);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.SRTM_DATA, downloadName, false, true);
}
if (info == null) {
info = getLocalIndexInfo(LocalIndexType.WIKI_DATA, downloadName, false, true);
}
return info;
}
public List<LocalIndexInfo> getLocalIndexInfos(String downloadName) {
List<LocalIndexInfo> list = new ArrayList<>();
LocalIndexInfo info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, false, false);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, true, false);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.SRTM_DATA, downloadName, false, false);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.WIKI_DATA, downloadName, false, false);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, false, true);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, true, true);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.SRTM_DATA, downloadName, false, true);
if (info != null) {
list.add(info);
}
info = getLocalIndexInfo(LocalIndexType.WIKI_DATA, downloadName, false, true);
if (info != null) {
list.add(info);
}
return list;
}
public List<LocalIndexInfo> getLocalIndexData(AbstractLoadLocalIndexTask loadTask) {
Map<String, String> loadedMaps = app.getResourceManager().getIndexFileNames();
List<LocalIndexInfo> result = new ArrayList<>();
loadObfData(app.getAppPath(IndexConstants.MAPS_PATH), result, false, loadTask, loadedMaps);
loadObfData(app.getAppPath(IndexConstants.ROADS_INDEX_DIR), result, false, loadTask, loadedMaps);
loadTilesData(app.getAppPath(IndexConstants.TILES_INDEX_DIR), result, false, loadTask);
loadSrtmData(app.getAppPath(IndexConstants.SRTM_INDEX_DIR), result, loadTask);
loadWikiData(app.getAppPath(IndexConstants.WIKI_INDEX_DIR), result, loadTask);
//loadVoiceData(app.getAppPath(IndexConstants.TTSVOICE_INDEX_EXT_ZIP), result, true, loadTask);
loadVoiceData(app.getAppPath(IndexConstants.VOICE_INDEX_DIR), result, false, loadTask);
loadFontData(app.getAppPath(IndexConstants.FONT_INDEX_DIR), result, false, loadTask);
loadObfData(app.getAppPath(IndexConstants.BACKUP_INDEX_DIR), result, true, loadTask, loadedMaps);
return result;
}
public List<LocalIndexInfo> getLocalFullMaps(AbstractLoadLocalIndexTask loadTask) {
Map<String, String> loadedMaps = app.getResourceManager().getIndexFileNames();
List<LocalIndexInfo> result = new ArrayList<>();
loadObfData(app.getAppPath(IndexConstants.MAPS_PATH), result, false, loadTask, loadedMaps);
return result;
}
private void loadVoiceData(File voiceDir, List<LocalIndexInfo> result, boolean backup, AbstractLoadLocalIndexTask loadTask) {
if (voiceDir.canRead()) {
//First list TTS files, they are preferred
for (File voiceF : listFilesSorted(voiceDir)) {
if (voiceF.isDirectory() && !MediaCommandPlayerImpl.isMyData(voiceF) && (Build.VERSION.SDK_INT >= 4)) {
LocalIndexInfo info = null;
if (TTSCommandPlayerImpl.isMyData(voiceF)) {
info = new LocalIndexInfo(LocalIndexType.TTS_VOICE_DATA, voiceF, backup, app);
}
if (info != null) {
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
//Now list recorded voices
for (File voiceF : listFilesSorted(voiceDir)) {
if (voiceF.isDirectory() && MediaCommandPlayerImpl.isMyData(voiceF)) {
LocalIndexInfo info = null;
info = new LocalIndexInfo(LocalIndexType.VOICE_DATA, voiceF, backup, app);
if (info != null) {
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
}
private void loadFontData(File fontDir, List<LocalIndexInfo> result, boolean backup, AbstractLoadLocalIndexTask loadTask) {
if (fontDir.canRead()) {
for (File fontFile : listFilesSorted(fontDir)) {
if (fontFile.isFile() && fontFile.getName().endsWith(IndexConstants.FONT_INDEX_EXT)) {
LocalIndexType lt = LocalIndexType.FONT_DATA;
LocalIndexInfo info = new LocalIndexInfo(lt, fontFile, backup, app);
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
private void loadTilesData(File tilesPath, List<LocalIndexInfo> result, boolean backup, AbstractLoadLocalIndexTask loadTask) {
if (tilesPath.canRead()) {
for (File tileFile : listFilesSorted(tilesPath)) {
if (tileFile.isFile() && tileFile.getName().endsWith(SQLiteTileSource.EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.TILES_DATA, tileFile, backup, app);
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
} else if (tileFile.isDirectory()) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.TILES_DATA, tileFile, backup, app);
if (!TileSourceManager.isTileSourceMetaInfoExist(tileFile)) {
info.setCorrupted(true);
}
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
private File[] listFilesSorted(File dir) {
File[] listFiles = dir.listFiles();
if (listFiles == null) {
return new File[0];
}
Arrays.sort(listFiles);
return listFiles;
}
private void loadSrtmData(File mapPath, List<LocalIndexInfo> result, AbstractLoadLocalIndexTask loadTask) {
if (mapPath.canRead()) {
for (File mapFile : listFilesSorted(mapPath)) {
if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.SRTM_DATA, mapFile, false, app);
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
private void loadWikiData(File mapPath, List<LocalIndexInfo> result, AbstractLoadLocalIndexTask loadTask) {
if (mapPath.canRead()) {
for (File mapFile : listFilesSorted(mapPath)) {
if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
LocalIndexInfo info = new LocalIndexInfo(LocalIndexType.WIKI_DATA, mapFile, false, app);
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
private void loadObfData(File mapPath, List<LocalIndexInfo> result, boolean backup, AbstractLoadLocalIndexTask loadTask, Map<String, String> loadedMaps) {
if (mapPath.canRead()) {
for (File mapFile : listFilesSorted(mapPath)) {
if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
LocalIndexType lt = LocalIndexType.MAP_DATA;
if (mapFile.getName().endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
lt = LocalIndexType.SRTM_DATA;
} else if (mapFile.getName().endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
lt = LocalIndexType.WIKI_DATA;
}
LocalIndexInfo info = new LocalIndexInfo(lt, mapFile, backup, app);
if (loadedMaps.containsKey(mapFile.getName()) && !backup) {
info.setLoaded(true);
}
updateDescription(info);
result.add(info);
loadTask.loadFile(info);
}
}
}
}
public enum LocalIndexType {
MAP_DATA(R.string.local_indexes_cat_map, R.drawable.ic_map, 10),
TILES_DATA(R.string.local_indexes_cat_tile, R.drawable.ic_map, 60),
SRTM_DATA(R.string.local_indexes_cat_srtm, R.drawable.ic_plugin_srtm, 40),
WIKI_DATA(R.string.local_indexes_cat_wiki, R.drawable.ic_plugin_wikipedia, 50),
TTS_VOICE_DATA(R.string.local_indexes_cat_tts, R.drawable.ic_action_volume_up, 20),
VOICE_DATA(R.string.local_indexes_cat_voice, R.drawable.ic_action_volume_up, 30),
FONT_DATA(R.string.fonts_header, R.drawable.ic_action_map_language, 35),
DEACTIVATED(R.string.local_indexes_cat_backup, R.drawable.ic_type_archive, 1000);
// AV_DATA(R.string.local_indexes_cat_av);;
@StringRes
private final int resId;
@DrawableRes
private int iconResource;
private final int orderIndex;
LocalIndexType(@StringRes int resId, @DrawableRes int iconResource, int orderIndex) {
this.resId = resId;
this.iconResource = iconResource;
this.orderIndex = orderIndex;
}
public String getHumanString(Context ctx) {
return ctx.getString(resId);
}
public int getIconResource() {
return iconResource;
}
public int getOrderIndex(LocalIndexInfo info) {
String fileName = info.getFileName();
int index = info.getOriginalType().orderIndex;
if (info.getType() == DEACTIVATED) {
index += DEACTIVATED.orderIndex;
}
if (fileName.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) {
index++;
}
return index;
}
public String getBasename(LocalIndexInfo localIndexInfo) {
String fileName = localIndexInfo.getFileName();
if (fileName.endsWith(IndexConstants.EXTRA_ZIP_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.EXTRA_ZIP_EXT.length());
}
if (fileName.endsWith(IndexConstants.SQLITE_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length());
}
if (this == VOICE_DATA) {
int l = fileName.lastIndexOf('_');
if (l == -1) {
l = fileName.length();
}
return fileName.substring(0, l);
}
if (this == FONT_DATA) {
int l = fileName.indexOf('.');
if (l == -1) {
l = fileName.length();
}
return fileName.substring(0, l).replace('_', ' ').replace('-', ' ');
}
int ls = fileName.lastIndexOf('_');
if (ls >= 0) {
return fileName.substring(0, ls);
} else if (fileName.indexOf('.') > 0) {
return fileName.substring(0, fileName.indexOf('.'));
}
return fileName;
}
}
}