package net.osmand.plus.download;
import android.annotation.SuppressLint;
import android.content.Context;
import net.osmand.OsmAndCollator;
import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@SuppressLint("DefaultLocale")
public class DownloadResourceGroup {
private final DownloadResourceGroupType type;
private final DownloadResourceGroup parentGroup;
// ASSERT: individualResources are not empty if and only if groups are empty
private final List<IndexItem> individualResources;
private final List<DownloadResourceGroup> groups;
protected final String id;
protected WorldRegion region;
public enum DownloadResourceGroupType {
// headers
WORLD_MAPS(R.string.world_maps),
REGION_MAPS(R.string.region_maps),
SRTM_HEADER(R.string.download_srtm_maps),
HILLSHADE_HEADER(R.string.download_hillshade_maps),
OTHER_MAPS_HEADER(R.string.download_select_map_types),
NAUTICAL_MAPS_HEADER(R.string.nautical_maps),
// headers with voice items
VOICE_HEADER_TTS(R.string.index_name_tts_voice),
VOICE_HEADER_REC(R.string.index_name_voice),
// headers with font items
FONTS_HEADER(R.string.fonts_header),
// headers with resources
OTHER_MAPS_GROUP(R.string.download_select_map_types),
OTHER_GROUP(R.string.other_menu_group),
SUBREGIONS(R.string.regions),
// screen items
VOICE_TTS(R.string.index_name_tts_voice),
FONTS(R.string.fonts_header),
VOICE_REC(R.string.index_name_voice),
OTHER_MAPS(R.string.download_select_map_types),
WORLD(-1),
REGION(-1);
final int resId;
private DownloadResourceGroupType(int resId) {
this.resId = resId;
}
public boolean isScreen() {
return this == WORLD || this == REGION || this == VOICE_TTS
|| this == VOICE_REC || this == OTHER_MAPS || this == FONTS;
}
public String getDefaultId() {
return name().toLowerCase();
}
public int getResourceId() {
return resId;
}
public boolean containsIndexItem() {
return isHeader() && this != SUBREGIONS && this != OTHER_GROUP && this != OTHER_MAPS_GROUP;
}
public boolean isHeader() {
return this == VOICE_HEADER_REC || this == VOICE_HEADER_TTS || this == SUBREGIONS
|| this == WORLD_MAPS || this == REGION_MAPS || this == OTHER_GROUP
|| this == HILLSHADE_HEADER || this == SRTM_HEADER
|| this == OTHER_MAPS_HEADER || this == OTHER_MAPS_GROUP
|| this == FONTS_HEADER || this == NAUTICAL_MAPS_HEADER;
}
public static String getVoiceTTSId() {
return "#" + OTHER_GROUP.name().toLowerCase() + "#" + VOICE_TTS.name().toLowerCase();
}
}
public DownloadResourceGroup(DownloadResourceGroup parentGroup, DownloadResourceGroupType type) {
this(parentGroup, type, type.getDefaultId());
}
public DownloadResourceGroup(DownloadResourceGroup parentGroup, DownloadResourceGroupType type, String id) {
boolean flat = type.containsIndexItem();
if (flat) {
this.individualResources = new ArrayList<IndexItem>();
this.groups = null;
} else {
this.individualResources = null;
this.groups = new ArrayList<DownloadResourceGroup>();
}
this.id = id;
this.type = type;
this.parentGroup = parentGroup;
}
public static WorldRegion getRegion(DownloadResourceGroup group) {
if (group != null) {
if (group.getRegion() != null) {
return group.getRegion();
} else if (group.getParentGroup() != null) {
return getRegion(group.getParentGroup());
} else {
return null;
}
} else {
return null;
}
}
public DownloadResourceGroup getRegionGroup(WorldRegion region) {
DownloadResourceGroup res = null;
if (this.region == region) {
res = this;
} else if (groups != null) {
for (DownloadResourceGroup group : groups) {
if (group.region == region) {
res = group;
break;
} else {
res = group.getRegionGroup(region);
if (res != null) {
break;
}
}
}
}
return res;
}
public void trimEmptyGroups() {
if(groups != null) {
for(DownloadResourceGroup gr : groups) {
gr.trimEmptyGroups();
}
Iterator<DownloadResourceGroup> gr = groups.iterator();
while(gr.hasNext()) {
DownloadResourceGroup group = gr.next();
if(group.isEmpty()) {
gr.remove();
}
}
}
}
public void createHillshadeSRTMGroups() {
if(getType().isScreen()) {
DownloadResourceGroup regionMaps = getSubGroupById(DownloadResourceGroupType.REGION_MAPS.getDefaultId());
if(regionMaps != null && regionMaps.size() == 1 && parentGroup != null && parentGroup.getParentGroup() != null &&
isEmpty(getSubGroupById(DownloadResourceGroupType.SUBREGIONS.getDefaultId()))) {
IndexItem item = regionMaps.individualResources.get(0);
DownloadResourceGroup screenParent = parentGroup.getParentGroup();
if(item.getType() == DownloadActivityType.HILLSHADE_FILE) {
DownloadResourceGroup hillshades =
screenParent.getSubGroupById(DownloadResourceGroupType.HILLSHADE_HEADER.getDefaultId());
if(hillshades == null) {
hillshades = new DownloadResourceGroup(screenParent, DownloadResourceGroupType.HILLSHADE_HEADER);
screenParent.addGroup(hillshades);
}
hillshades.addItem(item);
regionMaps.individualResources.remove(0);
} else if (item.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) {
DownloadResourceGroup hillshades = screenParent
.getSubGroupById(DownloadResourceGroupType.SRTM_HEADER.getDefaultId());
if (hillshades == null) {
hillshades = new DownloadResourceGroup(screenParent, DownloadResourceGroupType.SRTM_HEADER);
screenParent.addGroup(hillshades);
}
hillshades.addItem(item);
regionMaps.individualResources.remove(0);
}
}
DownloadResourceGroup subregs = getSubGroupById(DownloadResourceGroupType.SUBREGIONS.getDefaultId());
if(subregs != null) {
for(DownloadResourceGroup g : subregs.getGroups()) {
g.createHillshadeSRTMGroups();
}
}
}
}
private boolean isEmpty(DownloadResourceGroup subGroupById) {
return subGroupById == null || subGroupById.isEmpty();
}
public void addGroup(DownloadResourceGroup g) {
if(type.isScreen()) {
if(!g.type.isHeader()) {
throw new UnsupportedOperationException("Trying to add " + g.getUniqueId() + " to " + getUniqueId());
}
}
if(type.isHeader()) {
if(!g.type.isScreen()) {
throw new UnsupportedOperationException("Trying to add " + g.getUniqueId() + " to " + getUniqueId());
}
}
groups.add(g);
if (g.individualResources != null) {
final net.osmand.Collator collator = OsmAndCollator.primaryCollator();
final OsmandApplication app = getRoot().app;
final OsmandRegions osmandRegions = app.getRegions();
Collections.sort(g.individualResources, new Comparator<IndexItem>() {
@Override
public int compare(IndexItem lhs, IndexItem rhs) {
int lli = lhs.getType().getOrderIndex();
int rri = rhs.getType().getOrderIndex();
if(lli < rri) {
return -1;
} else if(lli > rri) {
return 1;
}
return collator.compare(lhs.getVisibleName(app.getApplicationContext(), osmandRegions),
rhs.getVisibleName(app.getApplicationContext(), osmandRegions));
}
});
}
}
public void addItem(IndexItem i) {
i.setRelatedGroup(this);
individualResources.add(i);
}
public boolean isEmpty() {
return isEmpty(individualResources) && isEmpty(groups);
}
private boolean isEmpty(List<?> l) {
return l == null || l.isEmpty();
}
public DownloadResourceGroup getParentGroup() {
return parentGroup;
}
public List<DownloadResourceGroup> getGroups() {
return groups;
}
public int size() {
return groups != null ? groups.size() : individualResources.size();
}
public DownloadResourceGroup getGroupByIndex(int ind) {
if(groups != null && ind < groups.size()) {
return groups.get(ind);
}
return null;
}
public IndexItem getItemByIndex(int ind) {
if(individualResources != null && ind < individualResources.size()) {
return individualResources.get(ind);
}
return null;
}
public DownloadResources getRoot() {
if (this instanceof DownloadResources) {
return (DownloadResources) this;
} else if (parentGroup != null) {
return parentGroup.getRoot();
}
return null;
}
public DownloadResourceGroupType getType() {
return type;
}
public DownloadResourceGroup getGroupById(String uid) {
String[] lst = uid.split("\\#");
return getGroupById(lst, 0);
}
public DownloadResourceGroup getSubGroupById(String uid) {
String[] lst = uid.split("\\#");
return getSubGroupById(lst, 0);
}
public List<IndexItem> getIndividualResources() {
return individualResources;
}
public WorldRegion getRegion() {
return region;
}
private DownloadResourceGroup getGroupById(String[] lst, int subInd) {
if (lst.length > subInd && lst[subInd].equals(id)) {
if (lst.length == subInd + 1) {
return this;
} else if (groups != null) {
return getSubGroupById(lst, subInd + 1);
}
}
return null;
}
private DownloadResourceGroup getSubGroupById(String[] lst, int subInd) {
for (DownloadResourceGroup rg : groups) {
DownloadResourceGroup r = rg.getGroupById(lst, subInd );
if (r != null) {
return r;
}
}
return null;
}
public String getName(Context ctx) {
if (region != null) {
return region.getLocaleName();
} else if (type != null && type.resId != -1) {
return ctx.getString(type.resId);
} else {
return id;
}
}
public String getUniqueId() {
if (parentGroup == null) {
return id;
}
return parentGroup.getUniqueId() + "#" + id;
}
public String getId() {
return id;
}
}