/*
 * PS3 Media Server, for streaming any medias to your PS3.
 * Copyright (C) 2008  A.Brochard
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License only.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package net.pms.dlna;

import net.pms.PMS;
import net.pms.dlna.virtual.VirtualFolder;
import net.pms.encoders.MEncoderVideo;
import net.pms.encoders.MEncoderWebVideo;
import net.pms.encoders.Player;
import net.pms.encoders.TSMuxerVideo;
import net.pms.dlna.RootFolder;  //regzamod, add
import net.pms.dlna.rz_IavSelCtl;  //regzamod, add

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileTranscodeVirtualFolder extends VirtualFolder {
	private static final Logger logger = LoggerFactory.getLogger(FileTranscodeVirtualFolder.class);
	private boolean resolved;
	private String name0;
	private DLNAResource sd;  //target(source) dlna
	
	public FileTranscodeVirtualFolder(String name, String name0, String thumbnailIcon, boolean copy,DLNAResource src) {
		super(name, name0, thumbnailIcon);
		this.sd=src;
		setSeed(sd);
	}
	public FileTranscodeVirtualFolder(String name, String name0, String thumbnailIcon, DLNAResource src) {
		super(name, name0, thumbnailIcon);
		this.sd=src;
		setSeed(sd);
	}

	private void setSeed(DLNAResource sd) {
		if(sd.getExt().isVideo()) {
			DLNAResource newChild = (DLNAResource) sd.clone();
			newChild.dname2=null;
			newChild.dname=null;
			newChild.setId(null);
			newChild.setPlayer(sd.getPlayer());
			newChild.setMedia(sd.getMedia());
			addChildInternal(newChild);
			logger.trace("Duplicate " + sd.getName() + " with player: " + sd.player2.toString());  
		}
	}
	
	@Override
	public int activate(int type) {
		if(PMS.rz_debug>1) PMS.dbg("FileTranscodeVirtualFolder.activate: called, type="+type);
		if(type!=1) {
			return 0;
		}
		resolve();
		return 0;
	}

	@Override
	public void resolve() {
		if(PMS.rz_debug>1) {
			PMS.dbg1("FileTranscodeVirtualFolder.resolve: called"
				+", name="+getName()
				+", resolved="+resolved
				+", sd.meta_type="+sd.meta_type
				+", sd.rz_Metafile="+sd.rz_Metafile
				+", sd.rz_Metafile.lastModified()="+(sd.rz_Metafile==null?0:sd.rz_Metafile.lastModified())
				+", getLastmodified="+getLastmodified()
			);
		}
		
		int do_resolve=0;
		if(!resolved) {
			if(PMS.rz_debug>1) PMS.dbg("FileTranscodeVirtualFolder.resolve: do_resolve=1: initial resolve");
			do_resolve=1;
		}
		else if(sd.rz_Metafile!=null && sd.meta_type==2) {
			if(sd.rz_Metafile.lastModified()>getLastmodified()) {
				if(PMS.rz_debug>1) PMS.dbg("FileTranscodeVirtualFolder.resolve:  do_resolve=2: resume updated");
				sd.resolve2();
				do_resolve=2;
			}
		}
		
		if(do_resolve>0) {
			resolved=false;
			if(do_resolve==2) {  //re-resolve
				ClearChildren();
				setSeed(sd);
			}
			resolve_in();
		}
	}
	
	public void resolve_in() {
		//called when corresponding "#-TRANSCODE-# folder opened
		//PMS.dbg("FileTranscodeVirtualFolder.resolve: Start resolved="+resolved+", name="+getName());
		
		DLNAResource newch=null;
		super.resolve();
		if (!resolved && getChildren().size() == 1) { //OK
			DLNAResource child = getChildren().get(0);
			child.resolve();
			
			//PMS.dbg("FileTranscodeVirtualFolder.resolve: child="+child.getName());
			//PMS.dbg("FileTranscodeVirtualFolder.resolve: Name="+child.getName()
			//	+"AudioCodes.size="+child.getMedia().getAudioCodes().size());
			
			if (child.getExt().getProfiles() != null && child.getMedia()!=null) {
				DLNAResource ref = child;
				
				//---------------------------------------------
				// create clippath botton, here is adequet?
				//---------------------------------------------
				/*
				DLNAResource pa=this;
				RootFolder root=PMS.getRootFolderByDlna(child);
				root.getSelClipPathVf(pa, null);
				pa.iavSelCtl=root.getSelClipBase();
				pa.addChild(pa.iavSelCtl.createClipAddBtn(child));
				*/
				
				//---------------------------------------------
				// create Normal Transcode folders
				//---------------------------------------------
				//PMS.dbg("FileTranscodeVirtualFolder.resolve: child="+child+", player="+child.getPlayer());
				//PMS.dbg("FileTranscodeVirtualFolder.resolve: getExt="+child.getExt());
				Player tsMuxer = null;
				
				//PMS.dbg("FileTranscodeVirtualFolder.resolve: child Name="+child.getName()+", isNoName()="+child.isNoName());
				addChapterFile(child);  //regzam, AutoChapder for default player

				//---- Standard Players for the media type of the Object
				for (int i = 0; i < child.getExt().getProfiles().size(); i++) {
					Player pl = PMS.get().getPlayer(child.getExt().getProfiles().get(i), child.getExt());
					//PMS.dbg("FileTranscodeVirtualFolder.resolve: child="+child.getName()+", entry="+i+", player="+pl);
					
					boolean add=true;
					if(pl!=null && pl.equals(child.getPlayer())) {  //default player
						if(child.getMedia().getAudioCodes().size()>0) {
							//yet need for all audios muxing?
							add=false;  //will be add later at per audio chapters
						}
					}
					else if(pl!=null && pl.id().equals(TSMuxerVideo.ID)) {  //tsmuxer
						if(child.getMedia().getAudioCodes().size()>0) {
							//yet need for all audios muxing?
							add=false;  //will be add later at per audio chapters
						}
					}
					
					//if (pl != null && !child.getPlayer().equals(pl)) {
					if (pl != null && add) {	//regzamod, test
						DLNAResource avisnewChild = (DLNAResource) child.clone();
						avisnewChild.setId(null);
						avisnewChild.setPlayer_f(pl);
						avisnewChild.setNoName(true);
						avisnewChild.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
						//avisnewChild.rz_MetaTransType[0]=0;
						//avisnewChild.rz_MetaTransType[1]=0;
						
						avisnewChild.setMedia(child.getMedia());
						if (avisnewChild.getPlayer().id().equals(MEncoderVideo.ID)) {
							//ref = avisnewChild;
						}
						if (avisnewChild.getPlayer().id().equals(TSMuxerVideo.ID)) {
							//tsMuxer = pl;
						}
						
						addChildInternal(avisnewChild);
						avisnewChild.rz_MetaTransType[0]=-1;
						avisnewChild.rz_MetaTransType[1]=-1;
						if(pl.id().equals(MEncoderWebVideo.ID)) {  //web player
							avisnewChild.rz_MetaTransType[0]=PMS.ENC_TRANSCODE;
						}
						addChapterFile(avisnewChild);
						//PMS.dbg("avisnewChild1 name="+avisnewChild.getDisplayName()+" ,rz_MetaTransType[0]="+avisnewChild.rz_MetaTransType[0]);
						
						if(pl.id().equals(MEncoderWebVideo.ID)) {  //web player
							DLNAResource avisnewChild2 = (DLNAResource) child.clone();
							avisnewChild2.setId(null);
							avisnewChild2.setPlayer_f(pl);
							avisnewChild2.setNoName(true);
							avisnewChild2.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
							avisnewChild2.setMedia(child.getMedia());
							avisnewChild2.rz_MetaTransType[0]=PMS.ENC_REMUX;
							avisnewChild2.rz_MetaTransType[1]=-1;
							addChildInternal(avisnewChild2);
							addChapterFile(avisnewChild2);
							//PMS.dbg("avisnewChild2 name="+avisnewChild2.getDisplayName()+" ,rz_MetaTransType[0]="+avisnewChild2.rz_MetaTransType[0]);
						}
					}
				}
				
				/*
				//---- add TsMuxeR player, if not to be created anywhere
				if(child.getMedia().getAudioCodes().size()<=0 && tsMuxer==null && child.sotype!=SO_VIDEO_STREAM) {
					DLNAResource avisnewChild = (DLNAResource) child.clone();
					avisnewChild.setId(null);
					avisnewChild.setPlayer_f(tsMuxer);
					avisnewChild.setNoName(true);
					avisnewChild.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
					avisnewChild.setMedia(child.getMedia());
					addChildInternal(avisnewChild);
					avisnewChild.rz_MetaTransType[0]=-1;
					avisnewChild.rz_MetaTransType[1]=-1;
					addChapterFile(avisnewChild);
				}
				*/
				
				//---- Per Audio streams for Default player(ref.getPlayer())
				//PMS.dbg("FileTranscodeVirtualFolder.resolve: ref="+ref+", player="+ref.getPlayer());
				for (int i = 0; i < child.getMedia().getAudioCodes().size(); i++) {
					DLNAResource newChildNoSub = (DLNAResource) ref.clone();
					newChildNoSub.setId(null);
					newChildNoSub.setPlayer_f(ref.getPlayer());
					newChildNoSub.setMedia(ref.getMedia());
					newChildNoSub.setNoName(true);
					newChildNoSub.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
					newChildNoSub.rz_MetaTransType[0]=-1;
					newChildNoSub.rz_MetaTransType[1]=-1;
					
					newChildNoSub.setMediaAudio(ref.getMedia().getAudioCodes().get(i));
					newChildNoSub.rz_MetaChannel_a_ffmpeg=i;	//regzamod
					newChildNoSub.setMediaSubtitle(new DLNAMediaSubtitle());
					newChildNoSub.getMediaSubtitle().setId(-1);
					addChildInternal(newChildNoSub);

					addChapterFile(newChildNoSub);

					//---- Per Subtitles, for default player(ref.getPlayer())
					for (int j = 0; j < child.getMedia().getSubtitlesCodes().size(); j++) {
						DLNAResource newChild = (DLNAResource) ref.clone();
						newChild.setId(null);
						newChild.setPlayer_f(ref.getPlayer());
						newChild.setMedia(ref.getMedia());
						newChild.setNoName(true);
						newChild.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
						newChild.rz_MetaTransType[0]=-1;
						newChild.rz_MetaTransType[1]=-1;
						
						newChild.setMediaAudio(ref.getMedia().getAudioCodes().get(i));
						newChildNoSub.rz_MetaChannel_a_ffmpeg=i;	//regzamod
						newChild.setMediaSubtitle(ref.getMedia().getSubtitlesCodes().get(j));
						addChildInternal(newChild);
						addChapterFile(newChild);

						//logger.debug("Duplicate " + ref.getName() + " with player: " + ref.getPlayer().toString() + " and aid: " + newChild.getMediaAudio().getId() + " and sid: " + newChild.getMediaSubtitle());
					}
				}
				
				//---- Per Audio Streams for TsMuxeR
				tsMuxer=PMS.get().getPlayer(TSMuxerVideo.ID);  //add allways/*
				if (tsMuxer != null) {
					for (int i = 0; i < child.getMedia().getAudioCodes().size(); i++) {
						DLNAResource newChildNoSub = (DLNAResource) ref.clone();
						newChildNoSub.setId(null);
						newChildNoSub.setPlayer_f(tsMuxer);
						newChildNoSub.setMedia(ref.getMedia());
						newChildNoSub.setNoName(true);
						newChildNoSub.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
						newChildNoSub.rz_MetaTransType[0]=-1;
						newChildNoSub.rz_MetaTransType[1]=-1;
						
						newChildNoSub.setMediaAudio(ref.getMedia().getAudioCodes().get(i));
						newChildNoSub.rz_MetaChannel_a_ffmpeg=i;	//regzamod
						addChildInternal(newChildNoSub);
						addChapterFile(newChildNoSub);
					}
				}

				//---- No Eccode Entry
				// meskibob: I think it'd be a good idea to add a "Stream" option (for PS3 compatible containers) 
				// to the #Transcode# folder in addition to the current options already in there.
				DLNAResource justStreamed = (DLNAResource) ref.clone();
				//if (justStreamed.getExt() != null && (justStreamed.getExt().ps3compatible() || justStreamed.isSkipTranscode())) {
				if (justStreamed.getExt() != null && child.sotype!=SO_VIDEO_STREAM) {  //regzam, allways add [no enode] entry
					justStreamed.setId(null);
					justStreamed.setPlayer_f(null);
					justStreamed.setMedia(ref.getMedia());
					justStreamed.setNoName(true);
					justStreamed.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
					justStreamed.rz_MetaTransType[0]=-1;
					justStreamed.rz_MetaTransType[1]=-1;
					
					addChildInternal(justStreamed);
					addChapterFile(justStreamed);
					
				}
			}
			setLastmodified(System.currentTimeMillis());
		}
		resolved = true;
	}

	private void addChapterFile(DLNAResource source) {
		if (PMS.getConfiguration().getChapterInterval() > 0 && PMS.getConfiguration().isChapterSupport()) {
			String dpname=source.getDisplayName();
			ChapterFileTranscodeVirtualFolder chapterFolder = new ChapterFileTranscodeVirtualFolder("Chapters:" + dpname, null, PMS.getConfiguration().getChapterInterval(),source);
			
			/*
			DLNAResource newSeekChild = (DLNAResource) source.clone();
			newSeekChild.setId(null);
			newSeekChild.setNoName(source.isNoName());  //inherit
			newSeekChild.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
			chapterFolder.addChildInternal(newSeekChild);
			*/
			addChildInternal(chapterFolder);
		}
	}

}
