
/*****************************************************
** Function to convert swarasthanam string to Aarohanam
** @param String (swarasthanam)
** @return Array of String
*******************************************************/
function getAarohanam(swarasthanam) {

	var swaraList = ['Sa', 'Ri1', 'Ri2', 'Ga2', 'Ga3', 'Ma1' , 'Ma2', 'Pa', 'Da1', 'Da2', 'Ni2', 'Ni3'];

	var aarohanam = new Array();

	var rishabamOccurred = false;
	var dhaivatamOccurred = false;

	for(i=0; i < swarasthanam.length; i++) {

		if(swarasthanam.substring(i,i+1) == '1') {

			if(isVivadhi(i)) {

					if(rishabamOccurred && swaraList[i] == 'Ri2') {
						swaraList[i] = 'Ga1';
					}
					else
					if(!rishabamOccurred && swaraList[i] == 'Ga2')	{
						swaraList[i] = 'Ri3';
					}

					if(dhaivatamOccurred && swaraList[i] == 'Da2') {
						swaraList[i] = 'Ni1';
					}
					else
					if(!dhaivatamOccurred && swaraList[i] == 'Ni2')	{
						swaraList[i] = 'Da3';
					}
			}

			aarohanam.push(swaraList[i]);

			if(swaraList[i] == 'Ri1' || swaraList[i] == 'Ri2') {
				rishabamOccurred = true;
			}

			if(swaraList[i] == 'Da1' || swaraList[i] == 'Da2') {
				dhaivatamOccurred = true;
			}
		}

	}

	return aarohanam;
}


/*******************************************************
** Function to convert swarasthanam string to Avarohanam
** @param String (swarasthanam)
** @return Array of String
********************************************************/
function getAvarohanam(swarasthanam) {

	var avarohanam = getAarohanam(swarasthanam);
	avarohanam.reverse();
	return avarohanam;
}

/******************************************************************
** Function to determine if the swarasthanam is a vivadhi or not
** @param number (position of the swara)
** @return boolean (true or false)
*******************************************************************/
function isVivadhi(position) {

	if(position == 2 || position == 3 || position == 9 || position ==10) {
		return true;
	}
	else {
		return false;
	}
}

/******************************************************************
** Function to search based on the song name
** @param String (songName)
** @return Array of FilmSongVO
*******************************************************************/
function findBySongName(songName) {

	var result = new Array();

	var soundexOfInput = soundex(songName);

	/*Soundex match of the whole string*/
	for (obj in raagaSwaraList) {
		for(index in raagaSwaraList[obj].songList) {

			if(soundexOfInput == soundex(raagaSwaraList[obj].songList[index].songName)) {
				var filmSongVO = new FilmSongVO(raagaSwaraList[obj].songList[index].songName
												, raagaSwaraList[obj].songList[index].filmName
												, raagaSwaraList[obj].raagaName
												, ''
												, ''
												, raagaSwaraList[obj].songList[index].singers
												, raagaSwaraList[obj].songList[index].songId);
				result.push(filmSongVO);
			}

			/*Mere Substring*/
			var dbSongName = raagaSwaraList[obj].songList[index].songName;
			if(dbSongName.toUpperCase().indexOf(songName.toUpperCase()) != -1) {
				var filmSongVO = new FilmSongVO(raagaSwaraList[obj].songList[index].songName
												, raagaSwaraList[obj].songList[index].filmName
												, raagaSwaraList[obj].raagaName
												, ''
												, ''
												, raagaSwaraList[obj].songList[index].singers
												, raagaSwaraList[obj].songList[index].songId);
				if (!isAlreadyPresent(result, filmSongVO)) {
					result.push(filmSongVO);
				}
			}
		}
	}

	/*Search in Vakra Raaga List*/
	for (obj in vakraRaagaList) {
		for(index in vakraRaagaList[obj].songList) {

			/* Soundex */
			if(soundexOfInput == soundex(vakraRaagaList[obj].songList[index].songName)) {
				var filmSongVO = new FilmSongVO(  vakraRaagaList[obj].songList[index].songName
												, vakraRaagaList[obj].songList[index].filmName
												, vakraRaagaList[obj].raagaName
												, vakraRaagaList[obj].aarohanam
												, vakraRaagaList[obj].avarohanam
												, vakraRaagaList[obj].songList[index].singers
												, vakraRaagaList[obj].songList[index].songId);
				result.push(filmSongVO);
			}

			/* Substring */
			if(vakraRaagaList[obj].songList[index].songName.toUpperCase().indexOf(songName.toUpperCase()) != -1) {
				var filmSongVO = new FilmSongVO(  vakraRaagaList[obj].songList[index].songName
												, vakraRaagaList[obj].songList[index].filmName
												, vakraRaagaList[obj].raagaName
												, vakraRaagaList[obj].aarohanam
												, vakraRaagaList[obj].avarohanam
												, vakraRaagaList[obj].songList[index].singers
												, vakraRaagaList[obj].songList[index].songId);
				if (!isAlreadyPresent(result, filmSongVO)) {
					result.push(filmSongVO);
				}
			}

		}
	}

	result = sortBySongRelevance(result, songName.trim());

	return result;
}

/******************************************************************
** Function to search based on the film name
** @param {String} (filmName)
** @param {boolean} flag to determine whether the search is for exact match
** or a fuzzy match
** @return Array of FilmSongVO
*******************************************************************/
function findByFilmName(filmName, exactMatchOnly) {

	var result = new Array();

	var soundexOfInput = soundex(filmName);

	for (obj in raagaSwaraList) {
		for(index in raagaSwaraList[obj].songList) {

			/*Soundex match of the whole string*/
			if(!exactMatchOnly && soundexOfInput == soundex(raagaSwaraList[obj].songList[index].filmName)) {
				var filmSongVO = new FilmSongVO(raagaSwaraList[obj].songList[index].songName
												, raagaSwaraList[obj].songList[index].filmName
												, raagaSwaraList[obj].raagaName
												, ''
												, ''
												, raagaSwaraList[obj].songList[index].singers
												, raagaSwaraList[obj].songList[index].songId);
				result.push(filmSongVO);
			}

			/*Mere Substring*/
			var dbFilmName = raagaSwaraList[obj].songList[index].filmName;
			if(dbFilmName.toUpperCase().indexOf(filmName.toUpperCase()) != -1) {
				var filmSongVO = new FilmSongVO(raagaSwaraList[obj].songList[index].songName
												, raagaSwaraList[obj].songList[index].filmName
												, raagaSwaraList[obj].raagaName
												, ''
												, ''
												, raagaSwaraList[obj].songList[index].singers
												, raagaSwaraList[obj].songList[index].songId);

				if (!isAlreadyPresent(result, filmSongVO)) {
					result.push(filmSongVO);
				}
			}
		}
	}

	/*Search in Vakra Raaga List*/
	for (obj in vakraRaagaList) {
		for(index in vakraRaagaList[obj].songList) {

			/* Soundex */
			if(!exactMatchOnly && soundexOfInput == soundex(vakraRaagaList[obj].songList[index].filmName)) {

				var filmSongVO = new FilmSongVO(  vakraRaagaList[obj].songList[index].songName
												, vakraRaagaList[obj].songList[index].filmName
												, vakraRaagaList[obj].raagaName
												, vakraRaagaList[obj].aarohanam
												, vakraRaagaList[obj].avarohanam
												, vakraRaagaList[obj].songList[index].singers
												, vakraRaagaList[obj].songList[index].songId);
				result.push(filmSongVO);
			}

			/* Substring */
			if(vakraRaagaList[obj].songList[index].filmName.toUpperCase().indexOf(filmName.toUpperCase()) != -1) {

				var filmSongVO = new FilmSongVO(  vakraRaagaList[obj].songList[index].songName
												, vakraRaagaList[obj].songList[index].filmName
												, vakraRaagaList[obj].raagaName
												, vakraRaagaList[obj].aarohanam
												, vakraRaagaList[obj].avarohanam
												, vakraRaagaList[obj].songList[index].singers
												, vakraRaagaList[obj].songList[index].songId);

				if (!isAlreadyPresent(result, filmSongVO)) {
					result.push(filmSongVO);
				}
			}

		}
	}

	return result;
}

/******************************************************************
** Function to search based on the advanced search criteria
** @param {SearchCriteriaVO} (searchCriteriaVO)
** @return Array of FilmSongVO
*******************************************************************/
function findBySearchCriteria(searchCriteriaVO) {

	var result = new Array();

	// Get all records
	result = findByFilmName('');

	if(searchCriteriaVO.singers && searchCriteriaVO.singers.length > 0) {
		result = filterBySingers(result, searchCriteriaVO.singers ,searchCriteriaVO.applyANDCondition);
	}

	if(searchCriteriaVO.directors && searchCriteriaVO.directors.length > 0) {
		result = filterByDirectors(result, searchCriteriaVO.directors ,searchCriteriaVO.applyANDCondition);
	}

	return result;
}


/******************************************************************
** Function to filter the results by Singers
** @param {Array} base result to filter further
** @param {Array} singer array of string
** @return {Array} of FilmSongVO
*******************************************************************/
function filterBySingers(result, singers, applyANDCondition) {

	var filteredResult = new Array();

	for(recordIndex in result) {

		filmSongVO = result[recordIndex];

		// If Exact Match required
		if(applyANDCondition == true && filmSongVO.singers) {

			if(isChildArrayFullyInMasterWSoundex(singers, filmSongVO.singers)) {
					var filmSongVO = new FilmSongVO(filmSongVO.songName
													, filmSongVO.filmName
													, filmSongVO.raagaName
													, ''
													, ''
													, filmSongVO.singers
													, filmSongVO.songId);
					filteredResult.push(filmSongVO);
			}

		} // exact match condition over

		// Even if one of the input is found
		for(singerIndex in filmSongVO.singers) { // For every singer of a particular song

			soundexOfDbSinger = soundex(filmSongVO.singers[singerIndex]);

			for(inputIndex=0; inputIndex< singers.length; inputIndex++) { // Compare with input singers values

				var soundexOfInput = soundex(singers[inputIndex]);

				/*Soundex match of the whole string*/
				if(soundexOfInput == soundexOfDbSinger && applyANDCondition == false) {
					var filmSongVO = new FilmSongVO(  filmSongVO.songName
													, filmSongVO.filmName
													, filmSongVO.raagaName
													, ''
													, ''
													, filmSongVO.singers
													, filmSongVO.songId);
					filteredResult.push(filmSongVO);
				}
			}
		} // Fuzzy match for loop over
	}

	return filteredResult;
}

/******************************************************************
** Function to filter the result by Directors
** @param {Array} base result to filter further
** @param {Array} directors array of string
** @return {Array} of FilmSongVO
*******************************************************************/
function filterByDirectors(result, directors, applyANDCondition) {

	var filteredResult = new Array();

	for(recordIndex in result) {

		filmSongVO = result[recordIndex];

		filmCrewObj = filmCrewList[filmSongVO.filmName.trim()];

		// If Exact Match required
		if(applyANDCondition == true && filmCrewObj && filmCrewObj.director) {

			if(directors.indexOf(filmCrewObj.director) != -1) {
					var filmSongVO = new FilmSongVO(  filmSongVO.songName
													, filmSongVO.filmName
													, filmSongVO.raagaName
													, ''
													, ''
													, filmSongVO.singers
													, filmSongVO.songId);
					filteredResult.push(filmSongVO);
			}

		} // exact match condition over



		if(applyANDCondition == false && filmCrewObj && filmCrewObj.director) {

			// Even if one of the input is found
			soundexOfDbSinger = soundex(filmCrewObj.director);

			for(inputIndex=0; inputIndex< directors.length; inputIndex++) { // Compare with input singers values

				var soundexOfInput = soundex(directors[inputIndex]);

				/*Soundex match of the whole string*/
				if(soundexOfInput == soundexOfDbSinger) {
					var filmSongVO = new FilmSongVO(  filmSongVO.songName
													, filmSongVO.filmName
													, filmSongVO.raagaName
													, ''
													, ''
													, filmSongVO.singers
													, filmSongVO.songId);
					filteredResult.push(filmSongVO);
				}
			}
		}
	}

	return filteredResult;
}


/******************************************************************
** Function to return list of all raaga in the database
** @return {Array} of RaagaVO
*******************************************************************/
function getAllRaagaList(){

	var result = new Array();

	for (obj in raagaSwaraList) { // For every Raaga

		raagaName = raagaSwaraList[obj].raagaName;
		aarohanam = getAarohanam(obj);
		avarohanam = getAvarohanam(obj);
		link  = raagaSwaraList[obj].isaiPayanam;

		if(raagaSwaraList[obj].songList) {
			numberOfSongs = raagaSwaraList[obj].songList.length;
		}
		else {
			numberOfSongs = 0;
		}
		melakarthaNumber = getMelakarthaNumber(obj);
		var raagaVO = new RaagaVO(raagaName, aarohanam, avarohanam, link, numberOfSongs, melakarthaNumber);
		result.push(raagaVO);
	}

	for (obj in vakraRaagaList) { // For every Vakra Raaga

		raagaName = vakraRaagaList[obj].raagaName;
		aarohanam = vakraRaagaList[obj].aarohanam;
		avarohanam = vakraRaagaList[obj].avarohanam;
		link  = vakraRaagaList[obj].isaiPayanam;

		if(vakraRaagaList[obj].songList) {
			numberOfSongs = vakraRaagaList[obj].songList.length;
		}
		else {
			numberOfSongs = 0;
		}

		var raagaVO = new RaagaVO(raagaName, aarohanam, avarohanam, link, numberOfSongs);
		result.push(raagaVO);
	}

	return result;
}


/******************************************************************
** Function to return the vakra raaga based on the input raaga name
** @param String (raagaName)
** @return JSON Object
*******************************************************************/
function findVakraRaaga(raagaName) {
	for (obj in vakraRaagaList) {
		if(obj.toUpperCase() == raagaName.toUpperCase()) {
			return vakraRaagaList[obj];
		}
		if(soundex(obj) == soundex(raagaName)) {
			return vakraRaagaList[obj];
		}
	}

}

/******************************************************************
** Function to return list of all film directors
** @return {Array} of strings
*******************************************************************/
function getAllFilmDirectors() {

	var result = new Array();

	for (obj in filmDirectorList) {
		filmDirectorVO = new FilmDirectorVO(obj, filmDirectorList[obj]);
		result.push(filmDirectorVO);
	}

	return result;
}

/******************************************************************
** Function to return the melakartha number
** @param String (swarasthanam)
** @return {number} (melakartha number)
*******************************************************************/
function getMelakarthaNumber(swarasthanam) {

	if(!isMelakartha(swarasthanam)) {
		return 0;
	}

	var melaNumber = 0;
	var sudhaMadhyamam = swarasthanam.substring(5,6);
	var pratiMadhyamam = swarasthanam.substring(6,7);

	if(sudhaMadhyamam == '1') {
		melaNumber = 0;
	}
	else
	if(pratiMadhyamam =='1') {
		melaNumber = 36;
	}

	var rishabamGandharam = swarasthanam.substring(1,5);

	if(rishabamGandharam =='1100') {
		melaNumber = melaNumber + 0*6;
	}
	else
	if(rishabamGandharam =='1010') {
		melaNumber = melaNumber + 1*6;
	}
	else
	if(rishabamGandharam =='1001') {
		melaNumber = melaNumber + 2*6;
	}
	else
	if(rishabamGandharam =='0110') {
		melaNumber = melaNumber + 3*6;
	}
	else
	if(rishabamGandharam =='0101') {
		melaNumber = melaNumber + 4*6;
	}
	else
	if(rishabamGandharam =='0011') {
		melaNumber = melaNumber + 5*6;
	}

	var dhaivatamNishadam = swarasthanam.substring(8,12);

	if(dhaivatamNishadam =='1100') {
		melaNumber = melaNumber + 0;
	}
	else
	if(dhaivatamNishadam =='1010') {
		melaNumber = melaNumber + 1;
	}
	else
	if(dhaivatamNishadam =='1001') {
		melaNumber = melaNumber + 2;
	}
	else
	if(dhaivatamNishadam =='0110') {
		melaNumber = melaNumber + 3;
	}
	else
	if(dhaivatamNishadam =='0101') {
		melaNumber = melaNumber + 4;
	}
	else
	if(dhaivatamNishadam =='0011') {
		melaNumber = melaNumber + 5;
	}

	melaNumber = melaNumber + 1;

	return melaNumber;
}

/******************************************************************
** Function to determine if the scale is a melakartha scale or not
** @param String (swarasthanam)
** @return boolean (true or false)
*******************************************************************/
function isMelakartha(swarasthanam) {

	var swaraCount = 0;
	for(i=0; i<swarasthanam.length; i++) {
		swaraCount = swaraCount + parseInt(swarasthanam.substring(i,i+1));
	}

	if(swaraCount != 7) {
		return false;
	}

	var shadjamam = swarasthanam.substring(0,1);
	var panchamam = swarasthanam.substring(7,8);

	if(shadjamam != '1' || panchamam != '1') {
		return false;
	}

	return true;
}
