/**
*
*/
package org.korsakow.services.export.task;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.korsakow.domain.Media;
import org.korsakow.domain.interf.IImage;
import org.korsakow.domain.interf.IMedia;
import org.korsakow.domain.interf.ISound;
import org.korsakow.domain.interf.IText;
import org.korsakow.domain.interf.IVideo;
import org.korsakow.ide.resources.ResourceType;
import org.korsakow.ide.task.AbstractTask;
import org.korsakow.ide.task.TaskException;
import org.korsakow.ide.util.FileUtil;
import org.korsakow.ide.util.Triple;
import org.korsakow.services.export.Exporter;
public class CreateFilenameMapTask extends AbstractTask
{
private final Exporter exporter;
private final String imageDir;
private final Collection<IImage> imageCollection;
private final String videoDir;
private final Collection<IVideo> videoCollection;
private final String soundDir;
private final Collection<ISound> soundCollection;
private final String textDir;
private final Collection<IText> textCollection;
private final String fontDir;
public CreateFilenameMapTask(
Exporter exporter,
String imageDir, Collection<IImage> imageCollection,
String videoDir, Collection<IVideo> videoCollection,
String soundDir, Collection<ISound> soundCollection,
String textDir, Collection<IText> textCollection,
String fontDir
)
{
this.exporter = exporter;
this.imageCollection = imageCollection;
this.imageDir = imageDir;
this.videoCollection = videoCollection;
this.videoDir = videoDir;
this.soundCollection = soundCollection;
this.soundDir = soundDir;
this.textCollection = textCollection;
this.textDir = textDir;
this.fontDir = fontDir;
}
@Override
public String getTitleString()
{
return "Analysing filenames...";
}
@Override
public void runTask() throws TaskException
{
Map<String, String> map;
try {
map = createFilenameMap(imageDir, imageCollection, videoDir, videoCollection, soundDir, soundCollection, textDir, textCollection, fontDir);
} catch (FileNotFoundException e) {
throw new TaskException(e);
}
// System.out.println(map.toString().replace(",", "\n"));
exporter.setFilenameMap(map);
}
public static void createMangledMap(String mediaDir, List<? extends IMedia> media,
Map<String, Triple<String, String, String>> mangledMap, String fileExtension)
throws FileNotFoundException
{
for (IMedia medium : media) {
String filenameBase = FileUtil.getFilenameWithoutExtension(new File(medium.getFilename()).getName());
String filenameOriginal = new File(mediaDir, filenameBase).getPath();
String filenameMangled = new File(mediaDir, filenameBase + "-" + medium.getId()).getPath();
Triple<String,String,String> desc = new Triple<String,String, String>(filenameOriginal, filenameMangled, fileExtension!=null?fileExtension:FileUtil.getFileExtension(medium.getFilename()));
mangledMap.put(medium.getAbsoluteFilename(), desc);
if (ResourceType.forId(medium.getType()) == ResourceType.VIDEO) {
IVideo video = (IVideo)medium;
if (video.getSubtitles() != null) {
String subtitleExtension = FileUtil.getFileExtension(video.getSubtitles());
String subtitleBase = FileUtil.getFilenameWithoutExtension(new File(video.getSubtitles()).getName());
String subtitleOriginal = new File(Exporter.SUBTITLE_DIR, subtitleBase).getPath();
String subtitleMangled = new File(Exporter.SUBTITLE_DIR, subtitleBase + "-" + medium.getId()).getPath();
Triple<String,String,String> subtitleDesc = new Triple<String,String, String>(subtitleOriginal, subtitleMangled, subtitleExtension);
mangledMap.put(Media.getAbsoluteFilename(video.getSubtitles()), subtitleDesc);
}
}
if (ResourceType.forId(medium.getType()) == ResourceType.SOUND) {
ISound sound = (ISound)medium;
if (sound.getSubtitles() != null) {
String subtitleExtension = FileUtil.getFileExtension(sound.getSubtitles());
String subtitleBase = FileUtil.getFilenameWithoutExtension(new File(sound.getSubtitles()).getName());
String subtitleOriginal = new File(Exporter.SUBTITLE_DIR, subtitleBase).getPath();
String subtitleMangled = new File(Exporter.SUBTITLE_DIR, subtitleBase + "-" + medium.getId()).getPath();
Triple<String,String,String> subtitleDesc = new Triple<String,String, String>(subtitleOriginal, subtitleMangled, subtitleExtension);
mangledMap.put(Media.getAbsoluteFilename(sound.getSubtitles()), subtitleDesc);
}
}
}
}
public static Map<String, String> createFilenameMap(
String imageDir, Collection<IImage> imageCollection,
String videoDir, Collection<IVideo> videoCollection,
String soundDir, Collection<ISound> soundCollection,
String textDir, Collection<IText> textCollection,
String fontDir
) throws FileNotFoundException
{
final CreateFilenameMapTask.SortMediaById sortById = new CreateFilenameMapTask.SortMediaById();
List<IImage> images = new ArrayList<IImage>(imageCollection);
Collections.sort(images, sortById);
List<IVideo> videos = new ArrayList<IVideo>(videoCollection);
Collections.sort(videos, sortById);
List<ISound> sounds = new ArrayList<ISound>(soundCollection);
Collections.sort(sounds, sortById);
List<IText> texts = new ArrayList<IText>(textCollection);
Collections.sort(texts, sortById);
// mangle all
Map<String, Triple<String,String, String>> mangledMap = new LinkedHashMap<String, Triple<String,String, String>>(); // want the choice of non-mangling to be consistent
CreateFilenameMapTask.createMangledMap(imageDir, images, mangledMap, null);
CreateFilenameMapTask.createMangledMap(videoDir, videos, mangledMap, FileUtil.getFileExtension(Exporter.VIDEO_EXPORT_FORMAT));
CreateFilenameMapTask.createMangledMap(soundDir, sounds, mangledMap, FileUtil.getFileExtension(Exporter.SOUND_EXPORT_FORMAT));
CreateFilenameMapTask.createMangledMap(textDir, texts, mangledMap, "txt");
mangledMap.put(new File(fontDir, "font.swf").getPath(), new Triple<String, String, String>("fonts", "font", "swf"));
Set<String> usedNamedMap = new LinkedHashSet<String>();
// demangle as many as possible
Map<String, String> resultMap = new LinkedHashMap<String, String>();
for (String key : mangledMap.keySet()) {
Triple<String,String, String> desc = mangledMap.get(key);
String filenameOriginal = desc.getFirst() + "." + desc.getThird();
String filenameMangled = desc.getSecond() + "." + desc.getThird();
// unique up to extension: this works well because media are split into folders by type, whereas a common scenario is something.jpg accompanied by something.mpg
if (!usedNamedMap.contains(filenameOriginal)) {
resultMap.put(key, filenameOriginal);
usedNamedMap.add(filenameOriginal);
} else {
resultMap.put(key, filenameMangled);
}
}
return resultMap;
}
public static final class SortMediaById implements Comparator<IMedia>
{
public int compare(IMedia o1, IMedia o2)
{
return (int)(o1.getId() - o2.getId());
}
}
}