package player

import (
	"container/list"
	"flag"
	. "netease_control_center/globals"
	"netease_control_center/interfaces/log"
	. "netease_control_center/interfaces/schedule"
)

var (
	PlayerHander map[PlayerType]PlayerHd = map[PlayerType]PlayerHd{
		PlayerType_Wifi:    nil,
		PlayerType_Dlna:    nil,
		PlayerType_Airplay: nil,
		PlayerType_Bt:      nil,
		PlayerType_Other:   nil,
	}

	NoticeTaskHander TaskHd
)

func init() {
	CloseBlueWhenReboot.RegisterCb(CloseBtRebootCb)
}

func PlayerInit() {
	GetSystemVolPer()

	initTtsApi()

	initNoticePlayer()

	initWifiPlayer()

	initDlnaPlayer()

	initAirPlayPlayer()

	initBtPlayer()

	//initNormalPlayer()

	initScenesPlayer()

	if !flag.Parsed() {
		flag.Parse()
	}
	if *log.TerminalCmd {
		log.Println(log.DebugLog, "Open terminal input cmd")
		go getInputCmd()
	}

	log.Println(log.DebugLog, "player init")
}

func initTtsApi() {
	// init tts api for direct tts play
	RegisteNoticePlayer(noticeTtsStart, noticeTtsStop)
}

func initWifiPlayer() {
	// init wifi player
	err, wifiPlayerHd := RegistePlayer(RegistedPlayer{
		Pause:              WifiPause,
		Play:               WifiPlay,
		Stop:               WifiStop,
		Seek:               WifiSeek,
		IsOnline:           WifiIsOnline,
		IfForcePause:       WifiIfForcePause,
		PlayNext:           WifiPlayNext,
		PlayPre:            WifiPlayPre,
		PrepareNext:        WifiPlayNext,
		GetSupportedSCmd:   WifiGetSUpportedSCmd,
		SetArg:             WifiSetArg,
		GetPlayerName:      WifiGetPlayerName,
		PlayerStatusChange: WifiPlayerStatusChange,
		Debug:              WifiDebug,
	}, PlayerType_Wifi)
	if nil != err {
		log.Println(log.ErrorLog, "register wifi player err")
		return
	}
	PlayerHander[PlayerType_Wifi] = wifiPlayerHd
}

func initDlnaPlayer() {
	// init dlna player
	err, dlnaPlayerHd := RegistePlayer(RegistedPlayer{
		Pause:              DlnaPause,
		Play:               DlnaPlay,
		Stop:               DlnaStop,
		Seek:               DlnaSeek,
		IsOnline:           DlnaIsOnline,
		IfForcePause:       DlnaIfForcePause,
		PlayNext:           DlnaPlayNext,
		PlayPre:            DlnaPlayPre,
		PrepareNext:        DlnaPlayNext,
		GetSupportedSCmd:   DlnaGetSUpportedSCmd,
		SetArg:             DlnaSetArg,
		GetPlayerName:      DlnaGetPlayerName,
		PlayerStatusChange: DlnaPlayerStatusChange,
		PlayerChangeCb:     DlnaPlayerChange,
	}, PlayerType_Dlna)
	if nil != err {
		log.Println(log.ErrorLog, "register dlna player err")
		return
	}
	PlayerHander[PlayerType_Dlna] = dlnaPlayerHd
}

func initAirPlayPlayer() {
	// init dlna player
	var err error
	var airPlayPlayerHd PlayerHd
	if AIRPLAY_MODE_ITSELF == AirPlay_Mode {
		err, airPlayPlayerHd = RegistePlayer(RegistedPlayer{
			Pause:              AirPlayPause2,
			Play:               AirPlayPlay2,
			Stop:               AirPlayStop2,
			Seek:               AirPlaySeek2,
			IsOnline:           AirPlayIsOnline2,
			IfForcePause:       AirPlayIfForcePause2,
			PlayNext:           AirPlayPlayNext2,
			PlayPre:            AirPlayPlayPre2,
			PrepareNext:        AirPlayPlayNext2,
			GetSupportedSCmd:   AirPlayGetSUpportedSCmd2,
			SetArg:             nil,
			GetPlayerName:      AirPlayGetPlayerName2,
			PlayerStatusChange: nil,
			PlayerChangeCb:     AirPlayChange2,
		}, PlayerType_Airplay)
	} else {
		err, airPlayPlayerHd = RegistePlayer(RegistedPlayer{
			Pause:              AirPlayPause,
			Play:               AirPlayPlay,
			Stop:               AirPlayStop,
			Seek:               AirPlaySeek,
			IsOnline:           AirPlayIsOnline,
			IfForcePause:       AirPlayIfForcePause,
			PlayNext:           AirPlayPlayNext,
			PlayPre:            AirPlayPlayPre,
			PrepareNext:        AirPlayPlayNext,
			GetSupportedSCmd:   AirPlayGetSUpportedSCmd,
			SetArg:             AirPlaySetArg,
			GetPlayerName:      AirPlayGetPlayerName,
			PlayerStatusChange: AirPlayPlayerStatusChange,
			PlayerChangeCb:     AirPlayChange,
		}, PlayerType_Airplay)
	}

	if nil != err {
		log.Println(log.ErrorLog, "register airplay player err")
		return
	}
	PlayerHander[PlayerType_Airplay] = airPlayPlayerHd
}

func initBtPlayer() {
	// init bt player
	err, btPlayerHd := RegistePlayer(RegistedPlayer{
		Pause:              BtPlayPause,
		Play:               BtPlayPlay,
		Stop:               BtPlayStop,
		Seek:               BtPlaySeek,
		IsOnline:           BtPlayIsOnline,
		IfForcePause:       BtPlayIfForcePause,
		PlayNext:           BtPlayPlayNext,
		PlayPre:            BtPlayPlayPre,
		PrepareNext:        BtPlayPlayNext,
		GetSupportedSCmd:   BtPlayGetSupportedSCmd,
		SetArg:             BtPlaySetArg,
		GetPlayerName:      BtGetPlayerName,
		PlayerStatusChange: BtPlayerStatusChange,
		PlayerChangeCb:     BtPlayerChange,
	}, PlayerType_Bt)
	if nil != err {
		log.Println(log.ErrorLog, "register bt player err")
		return
	}
	PlayerHander[PlayerType_Bt] = btPlayerHd
}

func initNormalPlayer() {
	// init wifi player
	err, normalPlayerHd := RegistePlayer(RegistedPlayer{
		Pause:              NormalPause,
		Play:               NormalPlay,
		Stop:               NormalStop,
		Seek:               NormalSeek,
		IsOnline:           NormalIsOnline,
		IfForcePause:       NormalIfForcePause,
		PlayNext:           NormalPlayNext,
		PlayPre:            NormalPlayPre,
		PrepareNext:        NormalPlayNext,
		GetSupportedSCmd:   NormalGetSUpportedSCmd,
		SetArg:             NormalSetArg,
		GetPlayerName:      NormalGetPlayerName,
		PlayerStatusChange: NormalPlayerStatusChange,
	}, PlayerType_Other)
	if nil != err {
		log.Println(log.ErrorLog, "register wifi player err")
		return
	}
	PlayerHander[PlayerType_Other] = normalPlayerHd
}

func initNoticePlayer() {
	// init notice play task
	taskhderr, taskhd := RegisteSTask(RegistedTask{
		Interrupt:           noticeInterrupt,
		Resume:              noticeResume,
		Do:                  noticeDo,
		IsActive:            noticeIsActive,
		GetName:             noticeGetName,
		GetTaskLevel:        noticeGetTaskLevel,
		GetSupportedSCmd:    noticeGetSupport,
		Debug:               noticePlayerDebug,
		CanBeInterruptByKey: noticeCanBeInterruptByKey,
		GetScheduleDomain: func() ScheduleDomain {
			return ScheduleDomain_Notice
		},
	})

	if nil != err {
		log.Println(log.ErrorLog, taskhderr.Error())
		return
	}
	NoticeTaskHander = taskhd
}

func initScenesPlayer() {
	initPlayListTask()
	initPlaySongTask()
	initQueryWeatherTask()
	initPlayQueryBirthdayTask()
}

func initPlayListTask() {
	var task RegistedSceneTask
	task.GetType = func() SStaskType {
		return SStaskType_Continuous
	}
	task.GetId = func() SSTaskId {
		return SSTaskId_PlayPlayList
	}
	task.Play = ScenesPlay
	task.PlayNext = ScenesPlayNext
	task.PlayPre = ScenesPlayPre
	task.Pause = ScenesPause
	task.Stop = ScenesStop
	task.Seek = ScenesPlaySeek

	task.PlayerStatusChange = ScenesPlayerStatusChange

	RegisteSceneTask(task)
}

func initPlaySongTask() {
	var task RegistedSceneTask
	task.GetType = func() SStaskType {
		return SStaskType_Continuous
	}
	task.GetId = func() SSTaskId {
		return SSTaskId_PlaySongList
	}
	task.Play = ScenesPlay
	task.PlayNext = ScenesPlayNext
	task.PlayPre = ScenesPlayPre
	task.Pause = ScenesPause
	task.Stop = ScenesStop
	task.Seek = ScenesPlaySeek

	task.PlayerStatusChange = ScenesPlayerStatusChange

	RegisteSceneTask(task)
}

func initQueryWeatherTask() {
	var task RegistedSceneTask
	task.GetType = func() SStaskType {
		return SStaskType_Once
	}
	task.GetId = func() SSTaskId {
		return SSTaskId_QueryWeather
	}
	task.Play = ScenesNoticePlay
	task.Stop = ScenesNoticeStop

	RegisteSceneTask(task)
}

func initPlayQueryBirthdayTask() {
	var task RegistedSceneTask
	task.GetType = func() SStaskType {
		return SStaskType_Continuous
	}
	task.GetId = func() SSTaskId {
		return SSTaskId_QueryBirthDay
	}

	task.Play = ScenesPlay
	task.PlayNext = ScenesPlayNext
	task.PlayPre = ScenesPlayPre
	task.Pause = ScenesPause
	task.Stop = ScenesStop
	task.Seek = ScenesPlaySeek

	task.PlayerStatusChange = ScenesPlayerStatusChange

	RegisteSceneTask(task)
}

/**
初始化播放列表信息
*/
func InitPlayer() {
	log.Printf(log.WarningLog, "initPlayer...............................\n")
	log.Println(log.DebugLog, "lock")
	playCtrlLock.Lock()
	LocalMusicList[HISTORY_MUSIC_LIST].Init()
	LocalMusicList[CUR_MUSIC_LIST].Init()
	LocalMusicList[RANDOM_MUSIC_LIST].Init()
	LocalMusicList[SCENES_MUSIC_LIST].Init()
	LocalMusicList[OTHERS_MUSIC_LIST].Init()
	LocalMusicList[PLAYSONG_MUSIC_LIST].Init()

	CurPosRecTmp = nil
	SceneCurPosRecTmp = nil

	LocalMusicFilter = MusicFilter{SongId: list.New(), AlbumId: list.New(), ArtistName: list.New()}
	PlayListSrcRec = PlayListSrcInfo{MusicListId: nil, MusicListIds: nil, MusicListIdIndex: INVALID_MUSIC_LEN,
		MusicListIdsLen: INVALID_MUSIC_LEN, HasInsert: false, HasMore: false, UpdateTime: 0, MusicSrc: MUSIC_LIST_NULL}
	ScenesPlayerListSrc = PlayListSrcInfo{MusicListId: nil, MusicListIds: nil, MusicListIdIndex: INVALID_MUSIC_LEN,
		MusicListIdsLen: INVALID_MUSIC_LEN, HasInsert: false, HasMore: false, UpdateTime: 0, MusicSrc: MUSIC_LIST_NULL}
	NormalPlayerListSrc = PlayListSrcInfo{MusicListId: nil, MusicListIds: nil, MusicListIdIndex: INVALID_MUSIC_LEN,
		MusicListIdsLen: INVALID_MUSIC_LEN, HasInsert: false, HasMore: false, UpdateTime: 0, MusicSrc: MUSIC_LIST_NULL}

	wifiPlayerSt = PlayerStatus{PlayerSrc: WIFI_SRC, MusicId: nil, MusicListId: nil, ContinuousTaskSt: MUSIC_ST_IDLE, CurPlayingPos: 0,
		TaskField:    FIELD_NULL,
		SingleTaskSt: AUDIO_ST_IDLE}

	CurCurrentStatus = NULL_FIELD_ST

	//清除榜单、每日推荐
	NewHotDailyRec[NEW_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[NEW_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[HOT_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[HOT_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[DAILY_PUSH-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[DAILY_PUSH-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[DENON_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[DENON_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[CLASSIC_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[CLASSIC_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[BEATPORT_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[BEATPORT_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[ORIGINAL_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[ORIGINAL_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[SORIGN_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[SORIGN_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[ACG_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[ACG_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[US_BILLBOARD_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[US_BILLBOARD_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	NewHotDailyRec[JP_ORICON_TOPLIST-NEW_TOPLIST].MusicListIndex = 0
	NewHotDailyRec[JP_ORICON_TOPLIST-NEW_TOPLIST].MusicListTimeStamp = 0

	DailyPushPlayedInfo = DailyPushRec{HasPlayed: false}

	NormalListMap = map[NormalListIndexType]*NormalList{
		NORMAL_LIST_PAGE: &NormalList{List: list.New(), CurPos: nil, HasMore: false},
		SCENES_LIST_PAGE: &NormalList{List: list.New(), CurPos: nil, HasMore: false},
		OTHERS_LIST_PAGE: &NormalList{List: list.New(), CurPos: nil, HasMore: false},
	}

	playCtrlLock.Unlock()
	log.Println(log.DebugLog, "unlock")
}
