/*
 * 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.configuration.PmsConfiguration;

/**
 * The ChapterFileTranscodeVirtualFolder is a {@link DLNAResource} container that
 * examines the media to be transcoded and creates several virtual children. This
 * is done by taking the full length of the media and creating virtual chapters
 * by means of a specified interval length. These virtual chapters are presented
 * to the user in the "#Transcode#" folder when the option "Chapter #Transcode#
 * folder support" is activated in the settings.
 */
public class ChapterFileTranscodeVirtualFolder extends VirtualFolder {
	private boolean resolved;
	private int interval;
	private int trans_type;
	private PmsConfiguration config=PMS.getConfiguration();
	private DLNAResource sd;  //target(source clone) dlna

	/**
	 * Constructor for a {@link ChapterFileTranscodeVirtualFolder}. The constructor
	 * does not create the children for this instance, it only sets the name, the
	 * icon for a thumbnail and the interval at which chapter markers must be placed
	 * when the children are created by {@link #resolve()}. 
	 * @param name The name of this instance.
	 * @param thumbnailIcon The thumbnail for this instance.
	 * @param interval The interval (in minutes) at which a chapter marker will be
	 * 			placed.
	 */
	public ChapterFileTranscodeVirtualFolder(String name, String thumbnailIcon, int interval, DLNAResource src) {
		super(name, thumbnailIcon);
		this.interval = interval;
		this.sd = src;
		setSeed(sd);
	}

	void setTrans(int type) {
		this.trans_type=type;
	}
	
	private void setSeed(DLNAResource sd) {
		String dpname=sd.getDisplayName();
		DLNAResource newSeekChild = (DLNAResource) sd.clone();
		newSeekChild.setId(null);
		newSeekChild.setSerialId(0);
		newSeekChild.setNoName(sd.isNoName());  //inherit
		newSeekChild.mflags|= DLNAResource.MF_UNDER_TRASCO_FOLDER; //regzamod
		addChildInternal(newSeekChild);
	}

	@Override
	public int activate(int type) {
		if(PMS.rz_debug>1) PMS.dbg1("ChapterFileTranscodeVirtualFolder.activate: called, type="+type+", name="+getName());
		if(type!=1) {
			return 0;
		}
		resolve();
		return 0;
	}

	/* (non-Javadoc)
	 * @see net.pms.dlna.DLNAResource#resolve()
	 */
	@Override
	public void resolve() {
		if(PMS.rz_debug>1) {
			PMS.dbg1("ChapterFileTranscodeVirtualFolder.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.dbg1("ChapterFileTranscodeVirtualFolder.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()) {
				sd.resolve2();
				if(PMS.rz_debug>1) PMS.dbg1("ChapterFileTranscodeVirtualFolder.resolve:  do_resolve=2: resume updated");
				do_resolve=2;
			}
		}
		
		if(do_resolve>0) {
			resolved=false;
			if(do_resolve==2) {  //re-resolve
				ClearChildren();
				setSeed(sd);
			}
			resolve_in();
		}
	}
	
	public void resolve_in() {
		super.resolve();
		double split_start= -1;
		double split_end= -1;
		double stt;

		if(PMS.rz_debug>1) PMS.dbg1("ChapterFileTranscodeVirtualFolder.resolve: Start, resolved="+resolved+", name="+getName());
		
		if (!resolved && getChildren().size() == 1) { //OK
			//this is top chapter
			DLNAResource child = getChildren().get(0);
			child.resolve();
			
			//PMS.dbg("ChapterFileTranscodeVirtualFolder: child.getDisplayName()="+child.getDisplayName());
			//PMS.dbg("ChapterFileTranscodeVirtualFolder: child.rz_MetaTransType[0]="+child.rz_MetaTransType[0]);
			//PMS.dbg("ChapterFileTranscodeVirtualFolder: child Name="+child.getName()+", isNoname="+child.isNoName());
			
			//child.rz_MetaTransType[0]=PMS.ENC_REMUX; //test
			//child.rz_MetaTransType[0]=trans_type;
			
			//regzamod, add start
			DLNAResource pa=getParent();
			if(pa!=null) {
				pa=getParent();
			}
			if(true || (pa!=null && pa.sotype==SO_RESUME_FOLDER)) {
				//PMS.dbg("ChapterFileTranscodeVirtualFolder.resolve: pa.sotype==SO_RESUME_FOLDER");
				split_start=child.getSplitRange().getStartOrZero();
				split_end=child.getSplitRange().getEndOrZero();
			}
			//clear part play range
			double duration=child.getMedia().getDurationInSeconds();
			if(duration<=0.0) {
				if(child.wmed_duration>0) {
					duration=child.wmed_duration;
				}
				else {
					duration=config.getRZ_unknown_duration_max();
				}
			}
			Range.Time range=new Range.Time(0.0, duration);
			child.setSplitRange(range);
			child.rz_isPartPlay=false;	
			child.rz_PartPlaySttp=0;	//clear part play bias
			//regzamod add end
			
			//int nbMinutes = (int) (child.getMedia().getDurationInSeconds() / 60);
			int nbMinutes = (int) (duration / 60);
			int nbIntervals = nbMinutes / interval;
			if(split_start>0) {
				nbIntervals+=1;  //to insert split_start chapter
			}
			if(split_end>0) {
				nbIntervals+=1;  //to insert split_end chapter
			}
			
			int c=1;	//chapter num
			String opt_str=null;
			boolean insf,inserted;
			
			if(PMS.rz_debug>1) {
				PMS.dbg1("ChapterFileTranscodeVirtualFolder.resolve_in: "
					+", duration="+duration
					+", nbIntervals="+nbIntervals
					+", split_start="+split_start
					+", name="+child.getName()
				);
			}
			
			for (int i = 1; i <= nbIntervals; i++) {
				
				// TODO: Remove clone(), instead create a new object from scratch to avoid unwanted cross references.
				//regzamod add start
				stt=60.0 * c * interval;  //per chapter start_time
				insf=false;
				if(split_start>0 && split_start<=stt) {
					stt=split_start;	//add split_start chapter
					split_start= -1;
					insf=true;
					opt_str=" <--- Part Start";
				}
				if(split_end>0 && split_end<=stt) {
					stt=split_end;	//add split_start chapter
					split_end= -1;
					insf=true;
					opt_str=" <--- Part End";
				}
				if(!insf) {
					c++;
				}
				//regzamod add end
				
				DLNAResource newChildNoSub = (DLNAResource) child.clone();
				newChildNoSub.setId(null);
				newChildNoSub.setPlayer(child.getPlayer());
				newChildNoSub.setMedia(child.getMedia());
				//newChildNoSub.setName(child.getName());
				//newChildNoSub.setNoName(true);  //need for force Mencoder Transcode, not pass to TsMuxer
				newChildNoSub.setNoName(child.isNoName());  //inherit
				newChildNoSub.setMediaAudio(child.getMediaAudio());
				newChildNoSub.setMediaSubtitle(child.getMediaSubtitle());
				//Range.Time range=new Range.Time(60.0 * i * interval, newChildNoSub.getMedia().getDurationInSeconds());
				range=new Range.Time(stt, duration);
				newChildNoSub.setSplitRange(range);
				if(newChildNoSub.getPlayer()==null) {
					newChildNoSub.rz_PartPlaySttp=stt;
				}
				if(PMS.rz_debug>1) {
					PMS.dbg1("ChapterFileTranscodeVirtualFolder.resolve: child i="+i+", start="+stt+", range="+range);
					PMS.dbg1("ChapterFileTranscodeVirtualFolder.resolve: part_duration="
						+newChildNoSub.getSplitRange());
				}
				addChildInternal(newChildNoSub);
				if(insf) {
					//newChildNoSub.setName(">> "+DLNAMediaInfo.getDurationString(range.getStart())+opt_str);//regzamod
					newChildNoSub.dname2=(">> "+DLNAMediaInfo.getDurationString(range.getStart())+opt_str);//regzamod
				}
				else {
					//newChildNoSub.setName(">> "+DLNAMediaInfo.getDurationString(range.getStart()));//regzamod
					newChildNoSub.dname2=(">> "+DLNAMediaInfo.getDurationString(range.getStart()));//regzamod
				}
			}
		}
		setLastmodified(System.currentTimeMillis());
		resolved = true;
	}

}
