def skipAudioCheck=true
def getAudiosFromListByFormat (format, listAudios) {
	def result=[]
	for (singleAudio in listAudios) {
		if (singleAudio.Format==format) {
			result.add(singleAudio)
		}
	}
	return result
}
def getBestChannelFromList (audiosFormatFound) {
	def bestChanel
	def currentValue=0
	for (myAudio2 in audiosFormatFound) {
		if (myAudio2.Channels>currentValue) {
			currentValue = myAudio2.Channels
			bestChanel = myAudio2
		}
	}
	return bestChanel
}
def getMaxQuality (listOfLanguageAudio) {
	def formatSet = ["PCM", "MLP FBA" ,"DTS", "FLAC", "AC-3", "E-AC-3", "EAC3", "AAC", "MPEG Audio", "MP3"]
	for (cFormat in formatSet) {
		def audiosFormatFound = getAudiosFromListByFormat(cFormat, listOfLanguageAudio);
		if (!audiosFormatFound.isEmpty()) {
			return getBestChannelFromList(audiosFormatFound)
		}
	}
	//no debería llegar aquí, si lo hace hay que documentar el problema indicando el/los formato/s no encontrado/s
	def formatosInvolucradosProblema='[formato_audio_no_encontrado-'
	for (audioFormatNotFound in listOfLanguageAudio) {
		formatosInvolucradosProblema = formatosInvolucradosProblema+' '+audioFormatNotFound.Format
	}
	formatosInvolucradosProblema=formatosInvolucradosProblema+']'
	throw new Exception(formatosInvolucradosProblema)
}

def bloqueAudio
def printAudio (audio2Print) {
	def idioma
	def idiomaOrigin = audio2Print.Language_String
	if (idiomaOrigin==null) {
		idiomaOrigin = audio2Print.Title
		if (idiomaOrigin =~ /(?i)\bcat\b/)
			idioma = "Cat"
		else if (idiomaOrigin =~ /(?i)\bcast\b|\bspa\b/)
			idioma = "Es"
	} else {
		idioma = idiomaOrigin.replace("Catalan","Cat").replace("Espanol / Espanol", "Es").replaceFirst(/(?i)(spanish|espa.ol)/,"Es").replace("(ES)","")
	}
	def formato_audio = audio2Print.Format_Commercial.replace("Dolby Digital":"Dolby").replace(" Plus","+")
													.replace("DTS-HD Master Audio","DTS-MA").replace("DTS-HD High Resolution Audio","DTS-HD-H")
													.replace("MPEG Audio","MPEG").replace("HE-AAC","AAC+")
													.replace(" with Dolby Atmos", "Atmos")
	def canales = audio2Print.Channels.replace(2:'2.0', 6:'5.1', 8:'7.1')
	return idioma + ' ' + formato_audio + ' ' + canales
}


/** Audio (ejecución) **/
	def catalanAudios=[]
	def spanishAudios=[]
	def englishAudios=[]
	def otherAudios=[]
	def audioDeclUndefined=false
	for (item in audio) {
		def idioma
		try {
			idioma = item.Language_String
			if (idioma==null) otherAudios.add("audio_no_def") //throw new Exception("[idioma_audio_no_definido0]")
			if ("Catalan"==idioma) catalanAudios.add(item)
			else if (idioma=~/(?i)(Spanish|Espa.ol)/) spanishAudios.add(item)
			else if ("English"==idioma) englishAudios.add(item)
			else if ("Undefined"==idioma) audioDeclUndefined=true
			else otherAudios.add(item)
		} catch (err) {
			if (idioma==null) {
				try { //si tampoco tiene item.Title
					def audioTitle=item.Title
					if (audioTitle!=null) {
						if (any{audioTitle}{0} =~ /(?i)\bcat\b/)
							catalanAudios.add(item)
						else if (any{audioTitle}{0} =~ /(?i)\bcast\b|\bspa\b/)
							spanishAudios.add(item)
						else if (any{audioTitle}{0} =~ /(?i)\bingl.es\b|\beng\b/)
							englishAudios.add(item)
						else otherAudios.add(item)
					}
				} catch (ex) {}
			} else if (!skipAudioCheck) throw err
		}
	}
	
	if (audioDeclUndefined || (catalanAudios.isEmpty() && spanishAudios.isEmpty() && englishAudios.isEmpty() && otherAudios.isEmpty()) ) {
		if (!skipAudioCheck) throw new Exception("[idioma_audio_no_definido]")
	}
	def tenimCat=false
	if (!catalanAudios.isEmpty()) {  //tenim català
		tenimCat=true
		def maxCat = getMaxQuality(catalanAudios)
		def blocCat = printAudio(maxCat)
		def tenimEsp = !spanishAudios.isEmpty()
		def blocEsp=''
		if (tenimEsp) {
			def maxEsp = getMaxQuality(spanishAudios)
			blocEsp = ', '+printAudio(maxEsp)
		}
		bloqueAudio =  blocCat + blocEsp
	} else if (!spanishAudios.isEmpty()) { //tenemos español
		def maxEsp = getMaxQuality(spanishAudios)
		bloqueAudio = printAudio(maxEsp) 
	}  else if (!englishAudios.isEmpty()) { //tenemos español
		if (!skipAudioCheck) throw new Exception("[idioma_audio_solo_ingles]")
	}  else if (!otherAudios.isEmpty()) { //tenemos español
		if (!skipAudioCheck) throw new Exception("[idioma_audio_marginal]")
	} else {
		if (!skipAudioCheck) throw new Exception("[idioma_audio_no_encontrado]")
	}
	if (bloqueAudio==null) bloqueAudio = "[audio_no_def]"
	else bloqueAudio = ' ['+bloqueAudio+']'
	/***********/
/*********************************************************/







def bloqueAudio2=''
def audiosMap = [:]
for (aud in audio) {
    def shortDesc = aud.Language_String3 !=null ? aud.Language_String3 
        : (aud.Title=~/(?i).+spa.+/?'spa': aud.Title.substring(0,3).toLowerCase())
    audiosMap[shortDesc] = audiosMap[shortDesc] ?: [:]
    audiosMap[shortDesc][aud.Format] = audiosMap[shortDesc][aud.Format] ?: []
    audiosMap[shortDesc][aud.Format] << aud
}

def groupedAudiosMap = [:]
for (audioElms in audiosMap) {
    def k = audioElms.key
    def v = audioElms.value
    if (!k.contains('+') && countAudiosInMap(v)>1) k += '+'
    def mQ = getMaxQuality2(v)
    def mQstr = (mQ==null || mQ.isEmpty()) ? 'und' : printAudio2(mQ)
    if (groupedAudiosMap.containsKey(mQstr)) groupedAudiosMap[mQstr].add(k)
    else groupedAudiosMap[mQstr] = [k]
}


audiosMap=null
def temp=''
for (audioGroup in groupedAudiosMap) {
    def k = audioGroup.key
    def v = audioGroup.value
    def gS = v.size()
    def str=''
    for (int i=0; i<gS; i++) {
        str += (v[i]!=null?v[i]:'und') +', '
        if (i==gS-1) {
            str = removeLastComa(str)+' '
            str += k+', '
        }
    }
    bloqueAudio2 += str
}
groupedAudiosMap=null
bloqueAudio2 = removeLastComa(bloqueAudio2)


/***********/
def removeLastComa(txt) {
    return txt.substring(0, txt.size()-2)
}
def getMaxQuality2 (mapAudioIndexedByFormat) { 
    def formatSet = ["PCM", "MLP FBA" ,"DTS", "FLAC", "AC-3", "E-AC-3", "EAC3", "AAC", "MPEG Audio", "MP3"]
	for (cFormat in formatSet) {
        if (mapAudioIndexedByFormat.containsKey(cFormat)){
            def difChannelsList = mapAudioIndexedByFormat[cFormat]
            return difChannelsList.size()==1 ? difChannelsList[0] : getBestChannelFromList2(difChannelsList)
        }
	}
    return null
}

def printAudio2 (audio2Print) {
	def formato_audio = audio2Print.Format
	switch (formato_audio) {
		case "AC-3"	-> formato_audio = "DD"
		case "E-AC-3" -> formato_audio = "DD+"
		case "MPEG Audio" -> formato_audio = "MPEG"
		case "DTS" -> {if(audio2Print.Format_Commercial.contains("Master Audio")) formato_audio="DTS-MA"}
	}
	def canales = audio2Print.Channels.replace(2:'2.0', 6:'5.1', 8:'7.1')
	return formato_audio + ' ' + canales
}
def getBestChannelFromList2 (audiosFormatFound) {
	def bestChanel
	def currentValue=0
	for (myAudio2 in audiosFormatFound) {
		if (myAudio2.Channels>currentValue) {
			currentValue = myAudio2.Channels
			bestChanel = myAudio2
		}
	}
	return bestChanel
}
def countAudiosInMap(audMap){
    int count=0
    for (aud in audMap) count += aud.value.size()
    return count
}





/************************/
return bloqueAudio + ' vs [' + bloqueAudio2 + ']'