import cv2
import datetime
import math
import os 
import random
import subprocess
#from moviepy.editor import VideoFileClip

#The channel bug that displays while the channel is playing episodes
buglocation = "/media/zella/anime/aaeachannelbug.png"
#the shows you would like this channel to play in individual folders under this folder
shows = "/media/zella/anime/shows"
#the "commercials" to fill up extra time in the hour. no folders, just videos in this folder.
commercials = "/media/zella/anime/commercials"
#the "station id" video that calls out what the channel is. have fun with it.
stationID = "/media/zella/anime/stationid/AAEAStationID.mp4"

secondsInHour = 3600
episodeBlockTime = 1560
minimumTime = 30

def get_next_show_episode(showNumber):
	if len(lineupStack[showNumber]) == 0:
		return None
	else:
		return lineupStack[showNumber].pop()
	
def get_next_commercial():
	if len(commercialStack) == 0:
		for file in os.listdir(commercials):
			commercialStack.append(os.path.join(commercials,file))
		random.shuffle(commercialStack)
		print("\nCommercial Stack reshuffled.\n" + "\nCommercial returned from stack at size: " + str(len(commercialStack)) + "\n")
		return commercialStack.pop()
	else:
		print("\nCommercial returned from stack at size: " + str(len(commercialStack)) + "\n")
		return commercialStack.pop()

#requires moviepy module. rounded up to nearest whole second, for simplicity.
#def get_video_length_in_seconds(videoFile):
#	clip = VideoFileClip(videoFile)
#	return math.ceil(clip.duration)
	
def get_video_length_in_seconds(video_path):
	cap = cv2.VideoCapture(video_path)
	total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
	frame_rate = cap.get(cv2.CAP_PROP_FPS)
	video_length = total_frames / frame_rate
	return math.ceil(video_length)

def get_remaining_seconds_in_hour():
	now = datetime.datetime.now()
	seconds_left_in_hour = 3600 - now.minute * 60 - now.second
	return seconds_left_in_hour

#Main Thread starts here

if os.path.exists("playlist.m3u"):
	os.remove("playlist.m3u")
else:
	print("\n playlist file does not exist.\n")

#open file in append mode
playlist = open('playlist.m3u',"a")

#a list of stacks of episode paths
lineupStack = []

#A list of commercials
commercialStack = []

#A list of showNumbers, for use later in shuffling episodes in a round robin manner randomly
showNumberList = []

#initialize show lists
showNumber = 0
for direc in os.listdir(shows):
	folder = os.path.join(shows,direc)
	if os.path.isdir(folder):
		print("\nOpening show " + str(showNumber) + " folder: " + folder + "\n")
		showEpisodes = []
		for file in os.listdir(folder):
			print(os.path.join(folder,file))
			showEpisodes.append(os.path.join(folder,file))
		lineupStack.append(showEpisodes)
		print("\n Added " + str(len(lineupStack[showNumber])) + " episodes from " + folder + "\n")
		showNumberList.append(showNumber)
		showNumber += 1

#reverse each show stack in the lineupStack list so we start from episode 1
for show in lineupStack:
	show.reverse()


#build season lineup station playlist using schedule:
#schedule:
#for boot hour
#get remaining seconds in hour
#if more than 30, stationid, play episode and fill rest with commercials and stationid
#if less, stationid and fill with commercials
#if more than 55, skip and build normal hour

#3600 seconds in an hour
#timeLeft = 3600

#In each hour:
#-Station ID video plays
#-episode (~25 minutes)
#-random commercial block (2 minutes)
#-Station ID video plays
#-random commercial block (2 minutes)
#-episode (~25 minutes)
#-random commercial block (2 minutes)
#-Station ID video plays
#-random commercial block (2 minutes)
#repeat until out of episodes

print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
print("              Building Playlist               ")
print("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")


episodesEmptyFlag = False
firstLoop = True
while not episodesEmptyFlag:
	if firstLoop:
		timeLeft = get_remaining_seconds_in_hour()
		firstLoop = False
	else:
		timeLeft = secondsInHour
	random.shuffle(showNumberList)
	showNumberListCount = 0
	while timeLeft > minimumTime:
		if timeLeft >= episodeBlockTime:
			print("Enough time for an episode block")
			#add station id
			timeLeft -= get_video_length_in_seconds(stationID)
			playlist.write(stationID + "\n")
			
			#add commercial. Maybe add a while loop here to add multiple commercials if one is too short
			nextAd = get_next_commercial()
			timeLeft -= get_video_length_in_seconds(nextAd)
			playlist.write(nextAd + "\n")
		
			#add tv episode	
			nextEpisode = ""
			while showNumberListCount < len(showNumberList):
				nextEpisode = get_next_show_episode(showNumberList[showNumberListCount])
				if nextEpisode is None:
					showNumberListCount += 1
					continue
				else:
					showNumberListCount += 1
					timeLeft -= get_video_length_in_seconds(nextEpisode)
					playlist.write(nextEpisode + "\n")
					print("\nEpisode " + nextEpisode + " added to playlist. " + str(len(lineupStack[showNumberList[showNumberListCount - 1]])) + " episodes left in stack\n")
					
					break
			if nextEpisode is None:
				print("Episodes exhausted! Completing Playlist!\n")
				episodesEmptyFlag = True
				break
			
			#add commercial.
			nextAd = get_next_commercial()
			timeLeft -= get_video_length_in_seconds(nextAd)
			playlist.write(nextAd + "\n")
			
			#add commercial.
			nextAd = get_next_commercial()
			timeLeft -= get_video_length_in_seconds(nextAd)
			playlist.write(nextAd + "\n")
			
		else:
			#no time for furtur episodes this hour
			print("Not enough time for another episode this hour. Padding")
			
						#add station id
			timeLeft -= get_video_length_in_seconds(stationID)
			playlist.write(stationID + "\n")
			
			#add commercial.
			nextAd = get_next_commercial()
			timeLeft -= get_video_length_in_seconds(nextAd)
			playlist.write(nextAd + "\n")
			
						#add commercial.
			nextAd = get_next_commercial()
			timeLeft -= get_video_length_in_seconds(nextAd)
			playlist.write(nextAd + "\n")

print("playlist file creation complete")
