package net.pms.dlna.virtual;

import net.pms.Messages;
import net.pms.PMS;
import net.pms.configuration.RendererConfiguration;

public class MediaLibrary extends VirtualFolder {
	private MediaLibraryFolder allFolder;

	public MediaLibraryFolder getAllFolder() {
		return allFolder;
	}
	private MediaLibraryFolder albumFolder;
	private MediaLibraryFolder artistFolder;
	private MediaLibraryFolder genreFolder;
	private MediaLibraryFolder playlistFolder;

	public MediaLibraryFolder getAlbumFolder() {
		return albumFolder;
	}

	public MediaLibrary(RendererConfiguration r) {
		super(Messages.getString("PMS.2"), null);
		this.setDefaultRenderer(r);
		init();
	}
	
	//-------------------------------------
	// How to assure order by name with case insensitive
	// (H2 DB seems to be case sensitive in defaults)
	//-------------------------------------
	// A) SELECT * FROM NOTES ORDER BY title NOCASE [ASC/DSC];  // NOCASE must be before ASC/DSC, if exists
	// B) SELECT * FROM NOTES ORDER BY LOWER(title);
	// C) SELECT * FROM NOTES ORDER BY LOWER(title), title;  	//Assure always UpperCase before LowerCase
	// D) alter session set nls_comp='ANSI'; & alter session set nls_sort='BINARY_CI';
	//-------------------------------------
	// MediaLibraryFolder(): sort default is PMS.SORT_NAME_NUM
	
	private void init() {
		//---- Audio Root ----
		VirtualFolder vfAudio = new VirtualFolder(Messages.getString("PMS.1"), null);
		
		//---- Audio All ----
		//allFolder = new MediaLibraryFolder(Messages.getString("PMS.11"), "select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 ORDER BY F.FILENAME ASC", MediaLibraryFolder.FILES, this.getDefaultRenderer());
		allFolder = new MediaLibraryFolder(Messages.getString("PMS.11") 
			,"SELECT DISTINCT A.ARTIST, A.TRACK, A.ALBUM, FILENAME, MODIFIED FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.ARTIST ASC, A.ALBUM ASC, A.TRACK ASC, F.FILENAME ASC"
			, MediaLibraryFolder.FILES, this.getDefaultRenderer());
		vfAudio.addChild(allFolder);
		
		// Force SORT_NAME_NUM: original sql_sort is logically good, but looks curious:
		// b/c unknown artist's titles are all sorted top and showed without artist name, this looks like sort broken
		allFolder.setLastSortType(PMS.SORT_NAME_NUM);  
		
		//---- All Audio Playlists
		playlistFolder = new MediaLibraryFolder(Messages.getString("PMS.9"), "select FILENAME, MODIFIED from FILES F WHERE F.TYPE = 16 ORDER BY F.FILENAME ASC", MediaLibraryFolder.PLAYLISTS, this.getDefaultRenderer());
		vfAudio.addChild(playlistFolder);
		
		//---- Audio By Artist
		artistFolder = new MediaLibraryFolder(Messages.getString("PMS.13"), new String[]{"SELECT DISTINCT A.ARTIST FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.ARTIST ASC", "select FILENAME, MODIFIED  from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST = '${0}' ORDER BY A.ALBUM ASC, A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(artistFolder);
		
		//---- Audio By Album
		albumFolder = new MediaLibraryFolder(Messages.getString("PMS.16"), new String[]{"SELECT DISTINCT A.ALBUM FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.ALBUM ASC", "select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.ALBUM = '${0}' ORDER BY A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(albumFolder);

		//---- Audio By Genre
		genreFolder = new MediaLibraryFolder(Messages.getString("PMS.19"), new String[]{"SELECT DISTINCT A.GENRE FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.GENRE ASC", "select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${0}' ORDER BY A.ARTIST ASC, A.ALBUM ASC, A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(genreFolder);
		
		//---- Audio By Artist/Album
		MediaLibraryFolder mlf6 = new MediaLibraryFolder(Messages.getString("PMS.22"), new String[]{
				"SELECT DISTINCT A.ARTIST FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.ARTIST ASC",
				"SELECT DISTINCT A.ALBUM FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST = '${0}' ORDER BY A.ALBUM ASC",
				"select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST = '${1}' AND A.ALBUM = '${0}' ORDER BY A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(mlf6);
		
		//---- Audio By Genre/Artist/Album
		MediaLibraryFolder mlf7 = new MediaLibraryFolder(Messages.getString("PMS.26"), new String[]{
				"SELECT DISTINCT A.GENRE FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.GENRE ASC",
				"SELECT DISTINCT A.ARTIST FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${0}' ORDER BY A.ARTIST ASC",
				"SELECT DISTINCT A.ALBUM FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${1}' AND A.ARTIST = '${0}' ORDER BY A.ALBUM ASC",
				"select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${2}' AND A.ARTIST = '${1}' AND A.ALBUM = '${0}' ORDER BY A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(mlf7);
		
		//---- Audio By Date
		//MediaLibraryFolder mlfAudioDate = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'd MMM yyyy') FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY F.MODIFIED DESC", "select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND FORMATDATETIME(MODIFIED, 'd MMM yyyy') = '${0}' ORDER BY A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES});
		MediaLibraryFolder mlfAudioDate = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY F.MODIFIED DESC", "select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') = '${0}' ORDER BY F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(mlfAudioDate);
		mlfAudioDate.rz_MetaSortType=PMS.SORT_ORIGIN;  //force date reverse (default==SORT_NAME_NUM)

		//---- Audio By Genre/Artist (add by regzam)
		MediaLibraryFolder mlf7b = new MediaLibraryFolder("By Genre/Artist", new String[]{
				"SELECT DISTINCT A.GENRE FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 ORDER BY A.GENRE ASC",
				"SELECT DISTINCT A.ARTIST FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${0}' ORDER BY A.ARTIST ASC",
				"select FILENAME, MODIFIED from FILES F, AUDIOTRACKS A where F.ID = A.FILEID AND F.TYPE = 1 AND A.GENRE = '${1}' AND A.ARTIST = '${0}' ORDER BY A.ALBUM ASC, A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(mlf7b);
		
		//---- Audio By Letter/Artist/Album
		MediaLibraryFolder mlf8 = new MediaLibraryFolder("By Letter/Artist/Album", new String[]{
				"SELECT ID FROM REGEXP_RULES ORDER BY ORDR ASC",
				"SELECT DISTINCT A.ARTIST FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST REGEXP (SELECT RULE FROM REGEXP_RULES WHERE ID = '${0}') ORDER BY A.ARTIST ASC",
				"SELECT DISTINCT A.ALBUM FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST = '${0}' ORDER BY A.ALBUM ASC",
				"SELECT FILENAME, MODIFIED FROM FILES F, AUDIOTRACKS A WHERE F.ID = A.FILEID AND F.TYPE = 1 AND A.ARTIST = '${1}' AND A.ALBUM = '${0}' ORDER BY A.TRACK ASC, F.FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfAudio.addChild(mlf8);
		
		addChild(vfAudio);

		//---- Image Root ----------------
		VirtualFolder vfImage = new VirtualFolder(Messages.getString("PMS.31"), null);
		
		//---- Image/All ----------------
		MediaLibraryFolder mlfPhoto01 = new MediaLibraryFolder(Messages.getString("PMS.32"), "TYPE = 2 ORDER BY FILENAME ASC", MediaLibraryFolder.FILES, this.getDefaultRenderer());
		vfImage.addChild(mlfPhoto01);
		mlfPhoto01.setLastSortType(PMS.SORT_NAME_NUM);  //force last folder's sort_type (default=SORT_ORIGIN, not sorted well)
		
		//---- Image/Date
		//MediaLibraryFolder mlfPhoto02 = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'd MMM yyyy') FROM FILES WHERE TYPE = 2 ORDER BY MODIFIED DESC", "TYPE = 2 AND FORMATDATETIME(MODIFIED, 'd MMM yyyy') = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES});
		MediaLibraryFolder mlfPhoto02 = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') FROM FILES WHERE TYPE = 2 ORDER BY MODIFIED DESC", "TYPE = 2 AND FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfImage.addChild(mlfPhoto02);
		mlfPhoto02.rz_MetaSortType=PMS.SORT_ORIGIN;  //force date reverse (default==SORT_NAME_NUM)
		
		//---- Image/Camera Model
		MediaLibraryFolder mlfPhoto03 = new MediaLibraryFolder(Messages.getString("PMS.21"), new String[]{"SELECT MODEL FROM FILES WHERE TYPE = 2 AND MODEL IS NOT NULL ORDER BY MODEL ASC", "TYPE = 2 AND MODEL = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfImage.addChild(mlfPhoto03);
		
		//---- Image/Film ISO
		MediaLibraryFolder mlfPhoto04 = new MediaLibraryFolder(Messages.getString("PMS.25"), new String[]{"SELECT ISO FROM FILES WHERE TYPE = 2 AND ISO > 0 ORDER BY ISO ASC", "TYPE = 2 AND ISO = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfImage.addChild(mlfPhoto04);
		
		addChild(vfImage);

		//---- Video Root ----------------
		VirtualFolder vfVideo = new VirtualFolder(Messages.getString("PMS.34"), null);
		
		//---- Video All ----------------
		MediaLibraryFolder mlfVideo01 = new MediaLibraryFolder(Messages.getString("PMS.35"), "TYPE = 4 ORDER BY FILENAME ASC", MediaLibraryFolder.FILES, this.getDefaultRenderer());
		vfVideo.addChild(mlfVideo01);
		mlfVideo01.setLastSortType(PMS.SORT_NAME_NUM);  //force last folder's sort_type (default=SORT_ORIGIN, not sorted well)
		
		//---- Video/Date
		//MediaLibraryFolder mlfVideo02 = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'd MMM yyyy') FROM FILES WHERE TYPE = 4 ORDER BY MODIFIED DESC", "TYPE = 4 AND FORMATDATETIME(MODIFIED, 'd MMM yyyy') = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES});
		MediaLibraryFolder mlfVideo02 = new MediaLibraryFolder(Messages.getString("PMS.12"), new String[]{"SELECT FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') FROM FILES WHERE TYPE = 4 ORDER BY MODIFIED DESC", "TYPE = 4 AND FORMATDATETIME(MODIFIED, 'yyyy/MM/dd') = '${0}' ORDER BY FILENAME ASC"}, new int[]{MediaLibraryFolder.TEXTS, MediaLibraryFolder.FILES}, this.getDefaultRenderer());
		vfVideo.addChild(mlfVideo02);
		mlfVideo02.rz_MetaSortType=PMS.SORT_ORIGIN;  //force date reverse (default==SORT_NAME_NUM)
		
		//---- video HD
		MediaLibraryFolder mlfVideo03 = new MediaLibraryFolder(Messages.getString("PMS.36"), "TYPE = 4 AND (WIDTH >= 1200 OR HEIGHT >= 700) ORDER BY FILENAME ASC", MediaLibraryFolder.FILES, this.getDefaultRenderer());
		vfVideo.addChild(mlfVideo03);
		mlfVideo03.setLastSortType(PMS.SORT_NAME_NUM);  //force last folder's sort_type (default=SORT_ORIGIN, not sorted well)
		
		//---- video SD
		MediaLibraryFolder mlfVideo04 = new MediaLibraryFolder(Messages.getString("PMS.39"), "TYPE = 4 AND (WIDTH < 1200 AND HEIGHT < 700) ORDER BY FILENAME ASC", MediaLibraryFolder.FILES, this.getDefaultRenderer());
		vfVideo.addChild(mlfVideo04);
		mlfVideo04.setLastSortType(PMS.SORT_NAME_NUM);  //force last folder's sort_type (default=SORT_ORIGIN, not sorted well)
		
		//---- DVD images
		MediaLibraryFolder mlfVideo05 = new MediaLibraryFolder("DVD Images", "TYPE = 32 ORDER BY FILENAME ASC", MediaLibraryFolder.ISOS, this.getDefaultRenderer());
		vfVideo.addChild(mlfVideo05);
		mlfVideo05.setLastSortType(PMS.SORT_NAME_NUM);  //force last folder's sort_type (default=SORT_ORIGIN, not sorted well)
		
		addChild(vfVideo);
	}

	public MediaLibraryFolder getArtistFolder() {
		return artistFolder;
	}

	public MediaLibraryFolder getGenreFolder() {
		return genreFolder;
	}

	public MediaLibraryFolder getPlaylistFolder() {
		return playlistFolder;
	}
}
