#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys, time
import glob
import codecs
import ctypes

sys.path.append('regzamod')
from Common.RzCmnSubs import dbg,dbg2,dbg0,error,setdbg
from Common.RzCmnSubs import isAudio,isImage,isVideo,isWebVideo,isWebContents,conv_encoding
from Common.RzCmnSubs import gs_encode_sys,gs_debug,gs_verbose,gs_ff_loglev
from Common.RzCmnSubs import gs_python,gs_prog_ytdl,gs_prog_ytdl_s,gs_prog_streamer,gs_streamer_conf

fp_ctl=None		#pos controll file descripter
fp_dbg=sys.stderr
ErrorMsg=None

# filenames
aav_statfile_n="aav_ctl"
aav_logfile_n="aav_log"

# file path
aav_statfile="aav_ctl.txt"
aav_logfile="aav_log.txt"

inited=False

# r 書き込み専用 
# w 書き込み専用 
# a 追加(ファイルを開く時、ファイルの参照点は自動的にファイルの末尾に移動) 
# r+ 更新(読み取りと書き込み) 
# w+ ファイルを空にした後、そのファイルを読み書き用に開く 
# a+ ファイルを読み書き用に開く、参照点は自動的にファイルの末尾に移動 
# b 他のオプションと一緒に指定すると、ファイルをバイナリモードで開く 

def init(temp_path,sess_id):
	global fp_dbg,fp_ctl,inited
	global aav_logfile,aav_statfile
	
	if(inited):
		return
	
	if not os.path.exists(temp_path):
		os.makedirs(temp_path)
	
	aav_logfile=temp_path+"/"+aav_logfile_n+"("+sess_id+").txt"
	aav_statfile=temp_path+"/"+aav_statfile_n+"("+sess_id+").txt"
	
	if(fp_dbg is None):
		if(os.path.isfile(aav_logfile)):
			fp_dbg=codecs.open(aav_logfile,"w+",'utf-8')
		else:
			fp_dbg=codecs.open(aav_logfile,"w+",'utf-8')
	if(fp_ctl is None):
		if(os.path.isfile(aav_statfile)):
			fp_ctl=open(aav_statfile,"r+")
		else:
			fp_ctl=open(aav_statfile,"w+")
	inited=True
	
def getErrorMsg(reset):
	global ErrorMsg
	str=ErrorMsg
	if(reset):
		ErrorMsg=None
	return str
	
def error_dp(disp,*arg):
	global ErrorMsg
	header="RzAAVplayer [ERROR]:"
	str=header+"".join(arg)
	dbg0(str)
	if(disp): #disp on renderer screen
		ErrorMsg=str

#---- set pos to play next
def setnxpos(mpos,spos,mmax=None):
	global fp_ctl
	if(mmax is not None):
		if(spos>=mmax):
			spos=0
		if(mpos>=mmax):
			mpos=0
	print >>fp_ctl, "mpos=%d, spos=%d, time=%f" % (mpos,spos,time.time())
	fp_ctl.flush()
		
#---- get pos to play next
def getnxpos(mode,listsz,clippath):
	global fp_ctl
	global aav_logfile,aav_statfile

	mpos=0
	spos=0
	cnt=0
	clippath_prev=None
	if(fp_ctl is None):
		if(os.path.isfile(aav_statfile)):
			fp_ctl=open(aav_statfile,"r+")
		else:
			fp_ctl=open(aav_statfile,"w+")

	for line in fp_ctl:
		pos=line.find("clippath=")
		if(pos>=0):
			str=line[pos+9:]
			#ar=str.split(",")
			#clippath_prev=ar[0].strip()
			clippath_prev=str.strip()
		pos=line.find("mpos=")
		if(pos>=0):
			cnt+=1
			str=line[pos+5:]
			ar=str.split(",")
			mpos=int(ar[0])
		pos=line.find("spos=")
		if(pos>=0):
			str=line[pos+5:]
			ar=str.split(",")
			spos=int(ar[0])
		if(mode==0 and cnt>0):
			# get first line
			break
	if(clippath_prev is None or clippath!=clippath_prev):
		mpos=0
		spos=0
				
	#--- min check
	if(spos<0):
		spos=0	
	if(mpos<0):
		mpos=0	
	
	#--- max check
	if(mpos>=listsz):
		mpos=0
	if(spos>=listsz):
		spos=0
	
	#--- reopen & init
	fp_ctl.close()
	fp_ctl=open(aav_statfile,"w+")
	print >>fp_ctl,"clippath=%s" % clippath
	setnxpos(mpos,spos)
	
	dbg("getnxpos: found mpos=%d, spos=%d, imgcnt=%d" % (mpos,spos,listsz))
	return (mpos,spos)

# get plain list of image/video/cca(playlist) under the clippath dir
def getFilelist(clippath,sort,findstr):
	
	list=[]
	dbg("getFilelist Start: clippath=%s" % (clippath))
	if(os.path.isfile(clippath)):
		#dbg("getFilelist: clippath=%s is File" % (clippath))
		fp=codecs.open(clippath,"r","utf-8")
		for line in fp:
			line=line.strip()
			if(not line.startswith('#') and len(line)>0):
				try:
					f=line
					list.append(f)
					# can't check media_type when entry isn't local (ex. url)
					#f=line.encode(gs_encode_sys)  # to make encode same as glob.glob
					#if(isImage(f)):
					#	list.append(f)
					#elif(isVideo(f)):
					#	list.append(f)
				except :
					dbg("getFilelist : encode error, clippath=%s" % (line))
					pass
		fp.close()
		sort=""  # no-sort
		return list		
	elif(os.path.isdir(clippath)):
		dbg("RzAAVsubs.getFilelist: clippath=%s found" % clippath)
		#imglist=glob.glob(clippath+"/*.*")
		#list0=glob.glob(unicode(clippath+"/*.*"))
		path=os.path.join(clippath,"*.*")
		list0=glob.glob(path)
		dbg("RzAAVsubs.getFilelist: clippath=%s entry_cnt=%d" % (clippath,len(list0)))
		#glob seems to return shift-jis string --> convert to unicode string
		#for i in range(len(list0)):
		#	list0[i]=list0[i].decode(gs_encode_sys)
	else:
		return list
		
	for f in list0:
		#f=os.path.normpath(f)
		#dbg("getFilelist: f=%s" % f)
		if(findstr!="" and f.find(findstr)<0):
			continue
		lf=f.lower()
		#uf=f.decode(gs_encode_sys)
		uf,enc=conv_encoding(f)
		#uf=f
		#f=f.decode(gs_encode_sys)
		#if(lf.endswith((".jpg",".png",".bmp",".gif"))):
		if(isImage(lf)):
			list.append(f)
		elif(lf.endswith((".cca"))):
			# .cca : special/simple playlist for RzAAVplayer, treated as sublist in (main)list
			# .cca format: simple lines of file_paths to play, path may be quoted by double/single-quotatios
			# .cca format: line stars with # or null line will be ignored
			# filelist in .cca must be "REMUXABLE AND STRICTLY SAME TYPE type of videos", or plain images
			list.append(uf)
		elif(lf.endswith((".pxm"))):
			#pxm is meta-file, get target file's path written in pxm
			dbg("getFilelist: pxm found type=%r, f=%r" % (type(f),f))
			fp=open(f,"r")
			for line in fp:
				line=line.strip()
				if(not line.startswith("#") and len(line)>0):
					f=None;
					if(f==None):
						pos=line.find("path=")
						if(pos>=0):
							f=line[pos+len("path="):].strip('\"\' ')
					if(f==None):
						pos=line.find("path_vf=")
						if(pos>=0):
							f=line[pos+len("path_vf="):].strip('\"\' ')
					if(f!=None):
						uf,enc=conv_encoding(f)
						if(isWebVideo(uf)):
							list.append(uf)
						if(os.path.isfile(uf)):
							if(isImage(uf)):
								list.append(uf)
							elif(isVideo(uf)):
								list.append(uf)
			fp.close()
			
		elif(isVideo(lf)):
			list.append(uf)
		elif(isWebVideo(lf)):
			list.append(uf)
		#---- python can't handle symbolic links on Windows
		#elif(lf.endswith((".jpg.lnk",".png.lnk",".bmp.lnk",".gif.lnk"))):
		#	list.append(uf)
		#else:
		#	list.append("unknown type:"+f)
			
	if(sort=="name"):
		#list=sorted(list,key=str.lower)
		list=sorted(list,key=str)
	elif(sort=="name_r"):
		#list=sorted(list,key=str.lower,reverse=True)
		list=sorted(list,key=str,reverse=True)
	elif(sort=="date"):
		list=sorted(list,key=os.path.getmtime)
	elif(sort=="date_r"):
		list=sorted(list,key=os.path.getmtime,reverse=True)
	#for i in range(len(list)):
	#	list[i]=list[i].decode(gs_encode_sys)
	return list
	
# get playable_list from plain_list 
# 1) expand .cca(a type of playlist) to file list
# 2) force list contains single type of media(either images or videos)
#    judging from first media type in the list.
#    b/c difficult now, to handle multi-media visuals in single audio-play

def getPlaylist(list,clippath,mpos,spos_in,can_multi_video):
	
	#---- set init
	spos=0
	video_loopcnt=30	# video list count, to be 
	mmax=len(list)
	if(mpos>=mmax):
		mpos=0
	if(spos>=mmax):
		spos=0
	spos_up=1	# last-play pos should be count-up'ed
	olist=[]
	rc=0
	if(mmax<1):
		error(1,"getPlaylist: clippath=%s, No clipfile found. use default clips" % clippath)
		rc=-1
		return (rc,olist,olist,mpos,spos,mmax,0)

	dbg("getPlaylist: clippath=%s, list size=%d, mpos=%d, spos=%d" % (clippath,mmax,mpos,spos))
	
	if(list[mpos].lower().endswith(".cca")):
		fp=open(list[mpos],"r")
		for line in fp:
			line=line.strip()
			if(not line.startswith("#") and len(line)>0):
				dbg("getPlaylist: .cca: append=%s" % line)
				file=line.strip('\"\'')
				if(os.path.isfile(file)):
					olist.append(file)
				else:
					dbg("getPlaylist: .cca: is not real file=%s" % file)
					#olist.append(line.strip())
		if(len(olist)<1):
			error(1,"getPlaylist: No valid clip in cca=%s , Use default clips" % list[mpos])
			rc=-2
			return (rc,olist,olist,mpos,spos,0)
		if(isImage(olist[0])):
			type="image"
		else:
			type="video"
		
		# cca list must be single type (image or video only)
		olist2=[]
		if(type=="image"):
			for e in olist:
				if(isImage(e)):
					olist2.append(e)
		else:	#video
			for e in olist:
				if(not isImage(e)):
					olist2.append(e)
			if(False):
				#followings will be done by mkconcat()
				if(len(olist2)<20):
					listsz=len(olist2)
					loopc=int(float(video_loopcnt)/listsz)+1
					dbg("listsz=%d loopcount=%d" % (listsz,loopc))
					for i in range(0,loopc):
						for j in range (0,listsz):
							olist2.append(olist2[j])
		fp.close()
		olist=olist2
		spos_up=0	# last-play pos should NOT be count-up'ed
	else: #"else ".cca"
		if(isImage(list[mpos])):
			type="image"
			pos=spos
			for i in range(len(list)):
				if(isImage(list[pos])):
					olist.append(list[pos])
				pos+=1
				if(pos>=len(list)):
					pos=0
		else:
			type="video"
			pos=spos
			if(can_multi_video):
				for i in range(len(list)):
					if(isVideo(list[pos])):
						olist.append(list[pos])
					elif(isWebVideo(list[pos])):
						olist.append(list[pos])
					pos+=1
					if(pos>=len(list)):
						pos=0
			else:
				#can't be multi video list --> force single video list
				pos=spos_in
				tgt=None
				for i in range(len(list)):
					if(isVideo(list[pos])):
						tgt=list[pos]
						break
					pos+=1
					if(pos>=len(list)):
						pos=0
				if(tgt is None):
					pass
				else:
					for i in range(len(list)):
						olist.append(tgt)
	
	if(gs_verbose):		
		dbg("getPlaylist: End rc=%d, type=%s, cliplist count=%d, mpos=%d, spos=%d" % (rc,type,len(olist),mpos,spos))
		#dbg("getPlaylist: list="+str(olist)) #str(olist)may cause error
		dbg("getPlaylist: Result list=%r" % olist) #str(olist)may cause error
	if(len(olist)<=0):
		rc= -1
	for i in range(len(olist)):
		uf,enc=conv_encoding(olist[i])
		olist[i]=uf
		
	return (rc,type,olist,mpos,spos,spos_up)

def mkconcat_old (alist,spos,concatf,max):
	fp=open(concatf,"w")
	p=spos
	mod=len(alist)
	for i in range(max):  # (0 to max-1)
		p=p % mod
		line=alist[p]
		print >>fp, "file '%s'" % line
		p+=1
	fp.close()

# create ffmpeg concat file (for audio concat,max)
def mkconcat (alist,spos,concatf,max):
	list=[]
	p=spos
	mod=len(alist)
	line=alist[p]
	extruct=0
	if(not line.startswith("http")):
		msfx=line.rsplit(".",2)
		if(len(msfx)==2):
			extruct=1
	if(extruct):
		#---- extruct only same-suffix entries
		# ffmpeg seems can't handle different-suffix files in concat
		sfx=msfx[1].lower()
		#ws_dbg("ws_concat: sfx=%s" % sfx)
		for i in range(mod):
			p1=p % mod
			line=alist[p1]
			if(line.lower().endswith(sfx)):
				list.append(line)
			p+=1
	else:
		for i in range(mod):
			p1=p % mod
			line=alist[p1]
			list.append(line)
			p+=1
	
	#---- write to concat file
	fp=codecs.open(concatf,"w","utf-8")
	mod=len(list)
	p=0
	for i in range(max):  # (0 to max-1)
		p1=p % mod
		line=list[p1]
		#replace ['] in path_name to ['\''], for ffmpeg concat 
		line=line.replace("'","'\\''")
		print >>fp, "file '%s'" % line
		p+=1
	fp.close()


#---- read-in audio playlist from file
def getAudioPlaylist_old(path):
	
	alist=[]  	# list of audio file path
	tlist=[[]]	# list of audio media tags
	rpos=0
	dbg("getAudioPlaylist Start: path=%s" % (path))
	if(os.path.isfile(path)):
		fp=codecs.open(path,"r","utf-8")
		for line in fp:
			line=line.strip()
			if(line.startswith('#') or len(line)<=0):
				continue
			if(line.startswith('path=')):
				str=line[len('path='):]
				alist.append(str.strip())
		fp.close()
	return (alist,tlist)

#----------------------------------------------------------------------------------
# main for test
#----------------------------------------------------------------------------------
if __name__ == '__main__':
	
	if(True):
		dbg("==== RzAAVsubs Test main executed!! ==============")
		clippath="C:/Documents and Settings/papa/My Documents/My Pictures/tv"
		clippath="C:/Documents and Settings/papa/My Documents/My Pictures/SceneTest"
		clippath=="C:/Documents and Settings/papa/My Documents/My Pictures/SceneClips"
		test=1
		
		fp=open("wk.log","w")
		if(len(sys.argv)>=2):
			test=int(sys.argv[1])
		if(len(sys.argv)>=3):
			clippath=sys.argv[2]

		print >>fp, "type=%d clippath=%s" % (test,clippath)
		
		if(test==1):
			print >>fp, "getPlaylist path=%s" % (clippath)
			(type,list,mpos,spos,mmax)=getPlaylist(clippath)
			for f in list:
				print >>fp, f
			print >>fp, "type=%s, list count=%d, mpos=%d, spos=%d" % (type,len(list),mpos,spos)
		elif(test==2):
			print >>fp, "getFilelist path=%s" % (clippath)
			list=getFilelist(clippath,"name")
			for f in list:
				print >>fp, f
			print >>fp, "list count=%d" % (len(list))
		fp.close()
