const defaultColor = "#555555"

const languages = {
			tamil: {name: "Tamil", color: "#75d795", code: "ta", text_align: "start", districts: []},
			malayalam: {name: "Malayalam", color: "#ff7c7c", code: "ml", text_align: "end", districts: []},
			kannada: {name: "Kannada", color: "#ffe77c", code: "kn", text_align: "middle", districts: []},
			telugu: {name: "Telugu", color: "#7c9dff", code: "te", text_align: "start", districts: []},
			marathi: {name: "Marathi", color: "#e0ff7c", code: "mr", text_align: "middle", districts: []},
			konkani: {name: "Konkani", color: "#9b7cff", code: "gom", text_align: "end", districts: []},
			hindi: {name: "Hindi", color: "#d17cff", code: "hi", text_align: "middle", districts: []},
			gujarati: {name: "Gujarati", color: "#7cffee", code: "gu", text_align: "middle", districts: []},
			oriya: {name: "Oriya", color: "#9bcc9f", code: "or", text_align: "middle", districts: []},
			bengali: {name: "Bengali", color: "#bf9a77", code: "bn", text_align: "middle", districts: []},
			punjabi: {name: "Punjabi", color: "#e84a35", code: "pa", text_align: "middle", districts: []},
			mizo: {name: "Mizo", color: "#a6a4de", code: "lus", text_align: "middle", districts: []},
			assamese: {name: "Assamese", color: "#c9535b", code: "as", text_align: "middle", districts: []},
			bhojpuri: {name: "Bhojpuri", color: "#b3b876", code: "bho", text_align: "end", districts: []},
			manipuri: {name: "Manipuri", color: "#c9afad", code: "mni-Mtei", text_align: "middle", districts: []},
			dogri: {name: "Dogri", color: "#9595e6", code: "doi", text_align: "middle", districts: []},
			nepali: {name: "Nepali", color: "#71998e", code: "ne", text_align: "middle", districts: []},
			urdu: {name: "Urdu", color: "#3fa179", code: "ur", text_align: "middle", districts: []},
			tulu: {name: "Tulu", color: "#dedc52", code: "tcy", text_align: "end", districts: []},
			maithali: {name: "Maithali", color: "#4472a6", code: "mai", text_align: "middle", districts: []},
			sindhi: {name: "Sindhi", color: "#e89931", code: "sd", text_align: "middle", districts: []},
			awadhi: {name: "Awadhi", color: "#847fb5", code: "awa", text_align: "middle", districts: []},
			};

// Credit: https://www.artcraftblend.com/blogs/colors/shades-of-pastel
const state2lang = {
		"Tamil Nadu": languages["tamil"],
		"Kerala": languages["malayalam"],
		"Karnataka": languages["kannada"],
		"Andhra Pradesh": languages["telugu"],
		"Telangana": languages["telugu"],
		"Maharashtra": languages["marathi"],
		"Goa": languages["konkani"],
		"Odisha": languages["oriya"],
		"Gujarat": languages["gujarati"],
		"Rajasthan": languages["hindi"],
		"Chhattisgarh": languages["hindi"],
		"Jharkhand": languages["hindi"], // DEFAULT
		"West Bengal": languages["bengali"],
		"Assam": languages["assamese"],
		"Tripura": languages["bengali"],
		"Mizoram": languages["mizo"],
		"Manipur": languages["manipuri"],
		"Sikkim": languages["nepali"],
		"Bihar": languages["bhojpuri"],
		"Madhya Pradesh": languages["hindi"],
		"Uttar Pradesh": languages["hindi"],
		"Uttarakhand": languages["hindi"], // DEFAULT
		"Haryana": languages["hindi"], // DEFAULT
		"Punjab": languages["punjabi"],
		"Himachal Pradesh": languages["hindi"], // DEFAULT
		"Ladakh": languages["dogri"],
		"Jammu and Kashmir": languages["dogri"],

		"Dadra and Nagar Haveli and Daman and Diu": languages["gujarati"],
		"Puducherry": languages["tamil"],
		"Lakshadweep": languages["malayalam"],
		"Delhi": languages["hindi"],
		"Chandigarh": languages["hindi"]
}

const district2lang = { // Should override state colors
	"Dakshina Kannada": languages["tulu"],

	"Muzaffarpur": languages["maithali"],
	"West Champaran": languages["maithali"],
	"East Champaran": languages["maithali"],
	"Vaishali": languages["maithali"],
	"Sitamarhi": languages["maithali"],
	"Sheohar": languages["maithali"],
	"Saharsa": languages["maithali"],
	"Madhepura": languages["maithali"],
	"Supaul": languages["maithali"],
	"Araria": languages["maithali"],
	"Katihar": languages["maithali"],
	"Kishanganj": languages["maithali"],
	"Purnia": languages["maithali"],
	"Banka": languages["maithali"],
	"Bhagalpur": languages["maithali"],
	"Munger": languages["maithali"],
	"Begusarai": languages["maithali"],
	"Jamui": languages["maithali"],
	"Khagaria": languages["maithali"],
	"Sheikhpura": languages["maithali"],
	"Lakhisarai": languages["maithali"],
	"Godda": languages["maithali"],
	"Deoghar": languages["maithali"],
	"Dumka": languages["maithali"],
	"Jamtara": languages["maithali"],
	"Sahibganj": languages["maithali"],
	"Pakur": languages["maithali"],
	"Darbhanga": languages["maithali"],
	"Madhubani": languages["maithali"],
	"Samastipur": languages["maithali"],

	"Moradabad": languages["urdu"],
	"Rampur": languages["urdu"],
	"Bijnor": languages["urdu"],
	"Amroha": languages["urdu"],
	"Meerut": languages["urdu"],
	"Ghaziabad": languages["urdu"],
	"Bulandshahr": languages["urdu"],
	"Aligarh": languages["urdu"],
	"Budaun": languages["urdu"],
	"Bareilly": languages["urdu"],
	"Sambhal": languages["urdu"],
	"Muzaffarnagar": languages["urdu"],
	"Saharanpur": languages["urdu"],
	"Shamli": languages["urdu"],
	"Hapur": languages["urdu"],

	"Kutch": languages["sindhi"],

	"Kanpur": languages["awadhi"],
   "Lakhimpur Kheri": languages["awadhi"],
   "Sitapur": languages["awadhi"],
   "Hardoi": languages["awadhi"],
   "Unnao": languages["awadhi"],
   "Fatehpur": languages["awadhi"],
   "Barabanki": languages["awadhi"],
   "Lucknow": languages["awadhi"],
   "Rae Bareli": languages["awadhi"],
   "Amethi": languages["awadhi"],
   "Bahraich": languages["awadhi"],
}

function responsivefy(svg) {
    // get container + svg aspect ratio
    var container = d3.select(svg.node().parentNode),
        width = parseInt(svg.style("width")),
        height = parseInt(svg.style("height")),
        aspect = width / height;

    // add viewBox and preserveAspectRatio properties,
    // and call resize so that svg resizes on inital page load
    svg.attr("viewBox", "0 0 " + width + " " + height)
        .attr("perserveAspectRatio", "xMinYMid")
        .call(resize);

    // to register multiple listeners for same event type,
    // you need to add namespace, i.e., 'click.foo'
    // necessary if you call invoke this function for multiple svgs
    // api docs: https://github.com/mbostock/d3/wiki/Selections#on
    d3.select(window).on("resize." + container.attr("id"), resize);

    // get width of container and resize svg to fit it
    function resize() {
        var targetWidth = Math.floor(container.node().getBoundingClientRect().width);
        svg.attr("width", targetWidth);
        svg.attr("height", Math.round(targetWidth / aspect));
    }
}

// Functions for calculating and dealing with language boundaries
function reverseCoordArrays(coords) {
    if (!Array.isArray(coords)) {
	 	return coords;
	 }
	 if (coords.every(item => Array.isArray(item) && item.length == 2 && item.every(val => Number.isFinite(val)))) {
		if (!turf.booleanClockwise(coords)) {
		 	return coords.reverse();
		} else {
			return coords;
		}
	}

	return coords.map(reverseCoordArrays);
}

function getOuterBoundaryPolygon(features) {
    // Check if we have features to process
    if (!features || features.length === 0) {
      console.warn("No features to process for boundary");
      return null;
    }

    // Handle single feature case
    if (features.length === 1) {
      return features[0];
    }

    let combined = turf.union(turf.featureCollection(features))

	 combined.geometry.coordinates = reverseCoordArrays(combined.geometry.coordinates);
    return combined;
}

function district2langFunc(d) {
    if (district2lang.hasOwnProperty(d.properties.district)) {
				return district2lang[d.properties.district];
		} else if (state2lang.hasOwnProperty(d.properties.st_nm)) {
				return state2lang[d.properties.st_nm];
		} else {
				return undefined;
		}
}

function stateOrDistrictOrLanguage(d) {
	if (typeof d.properties.district !== 'undefined') {
		return "district"
	} else {
		if (typeof d.properties.lang_name !== 'undefined') {
			return "language"
		} else {
			return "state"
		}
	}
}


//	const mapWidth = document.getElementById("indiaMap").getAttribute("width")
//	const mapHeight = document.getElementById("indiaMap").getAttribute("height")
let mapWidth = /*window.innerWidth - */document.querySelector("#svgContainer").offsetWidth * 0.85;
// const mapHeight = document.querySelector("#svgContainer").offsetHeight;
let mapHeight = (window.innerHeight - document.querySelector("#svgContainer").getBoundingClientRect().top);

if (window.innerWidth <= 768) {
	mapWidth *= 1.5;
	mapHeight *= 1.5;
}

const svg = d3.select("#svgContainer")
			.append('svg')
		.attr('width', mapWidth.toString())
      .attr('height', (mapHeight).toString())
//      .attr('viewbox', '0 0 ' + mapWidth.toString() + ' ' + mapHeight.toString())
//		.attr('preserveAspectRatio', "xMidYMin")
			.attr('id', 'indiaMap')
      //   .call(responsivefy);

function drawMap(world) {
	let projection = null;
	if (window.innerWidth > 1366) {
		projection = d3.geoMercator().fitSize([mapWidth, mapHeight], world)
	} else {
		projection = d3.geoMercator().fitWidth(mapWidth, world)
	}
	const path = d3.geoPath().projection(projection);

   requestAnimationFrame(() => {
    const newSvg = d3.select('svg');
    const bbox = newSvg.node().getBBox();
    const originalWidth = +newSvg.attr("width");
    newSvg
   .attr("viewBox", `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`)
//   .attr("viewBox", `0 ${bbox.y} ${originalWidth} ${bbox.height}`)
   .attr("width", bbox.width)
   .attr("height", bbox.height)
 //  .style("display", "block")
 //  .style("max-height", "100%"); // optional: keep it scalable in a flexbox
   });


	const states = svg.selectAll("g")
	.data(world.features)
	.enter()
	.append("g");

	states.append("path")
		.attr("d", path)
		.attr("class", d => stateOrDistrictOrLanguage(d))
		.attr("id", function(d) {
				if (stateOrDistrictOrLanguage(d) === "language") {
						return languages[d.properties.lang_name.toLowerCase()].code + "langMap";
				}
		})
		.attr("fill", function(d) {
		    if (stateOrDistrictOrLanguage(d) === "language") {
		    	return languages[d.properties.lang_name.toLowerCase()].color;
		    }
		})
		.each(function(d) {
				if (stateOrDistrictOrLanguage(d) === "district") {
						const districtLang = district2langFunc(d);
						if (typeof districtLang !== 'undefined') {
							districtLang.districts.push(d)
						}
				}
				// Hide map load spinner after map has loaded
				document.getElementById("mapLoadSpinner").classList.add("hide");
				document.querySelector("svg").classList.add("show");

		})
		.append("title") // Tooltip
		.text(d => d.properties.district);

	const textItems = svg.selectAll("g.textItem").data(world.features).enter().append("g");
	textItems.append("text")
      .attr("x", function(d) {
				if (stateOrDistrictOrLanguage(d) == "language") {
					rtv = projection(d3.geoCentroid(d))[0];
					if (d.properties.lang_name == "Kannada") {
						rtv -= 20;
					}
               if (d.properties.lang_name == "Tamil") {
       	          rtv -= 10;
	       }
               if (d.properties.lang_name == "Kannada" && window.innerWidth <= 768) {
                  rtv += 15;
               }
               if (d.properties.lang_name == "Maithali") {
                  rtv += 10;
               }
               if (d.properties.lang_name == "Konkani") {
                  rtv -= 15;
               }
               if (d.properties.lang_name == "Bengali") {
                  rtv -= 15;
               }
					return rtv
				}
			})
      .attr("y", function(d) {
				if (stateOrDistrictOrLanguage(d) == "language") {
					rtv = projection(d3.geoCentroid(d))[1]
               if (d.properties.lang_name == "Kannada") {
		  if (window.innerWidth > 768) {
                 	 rtv += 10;
      		  }
               }
               if (d.properties.lang_name == "Tamil") {
                  rtv -= 10;
               }
               if (d.properties.lang_name == "Malayalam") {
                  rtv += 10;
               }
               if (d.properties.lang_name == "Gujarati") {
                  rtv -= 10;
               }
               if (d.properties.lang_name == "Mizo") {
                  rtv += 20;
               }
               if (d.properties.lang_name == "Nepali") {
                  rtv -= 10;
               }
               if (d.properties.lang_name == "Bengali") {
                  rtv += 25;
               }
	       if (d.properties.lang_name == "Hindi") {
		       if (window.innerWidth > 768) {
		       rtv += 3 * parseFloat(getComputedStyle(document.documentElement).fontSize); // rem
		       }
	       }

               return rtv
				}
		})	
	  .attr("class", "translationText")
	  .attr("id", function(d) {
			if (stateOrDistrictOrLanguage(d) == "language") {
				return d.properties.lang_code+"Text"
			} else {
				d3.select(this).remove()
			}
	  })
      .text(function(d) {
			if (stateOrDistrictOrLanguage(d) == "language") {
				return d.properties.lang_name;
			} else {
				d3.select(this).remove() // Only add this attribute if the element is a language
			}
		})
      .attr("text-anchor", d => typeof d.properties.lang_name != "undefined" && languages[d.properties.lang_name.toLowerCase()].text_align)
      .attr("fill", "black")

   // Romanization
	textItems.append("text")
      .attr("x", d => stateOrDistrictOrLanguage(d) == "language" ? 
							document.getElementById(d.properties.lang_code + "Text").getAttribute("x") : 
							projection(d3.geoCentroid(d))[0])
      .attr("y", d => stateOrDistrictOrLanguage(d) == "language" ? 
							parseFloat(document.getElementById(d.properties.lang_code + "Text").getAttribute("y")) + parseFloat(getComputedStyle(document.getElementsByClassName('translationText')[0]).getPropertyValue('font-size')) :
			 				projection(d3.geoCentroid(d))[1])
	  .attr("class", "romanizationText")
	  .attr("id", function(d) {
			if (stateOrDistrictOrLanguage(d) == "language") {
				return d.properties.lang_code+"Romanization"
			} else {
				d3.select(this).remove()
			}
	  })
      .each(function(d) {
			if (!stateOrDistrictOrLanguage(d) == "language") {
				d3.select(this).remove() // Only add this attribute if the element is a language
			}
		})
      .attr("text-anchor", d => typeof d.properties.lang_name != "undefined" && languages[d.properties.lang_name.toLowerCase()].text_align)
      .attr("fill", "black")

   // Language
	textItems.append("text")
      .attr("x", d => stateOrDistrictOrLanguage(d) == "language" ? 
							document.getElementById(d.properties.lang_code + "Text").getAttribute("x") : 
							projection(d3.geoCentroid(d))[0])
      .attr("y", d => stateOrDistrictOrLanguage(d) == "language" ? 
							parseFloat(document.getElementById(d.properties.lang_code + "Text").getAttribute("y")) - parseFloat(getComputedStyle(document.getElementsByClassName('translationText')[0]).getPropertyValue('font-size')) :
			 				projection(d3.geoCentroid(d))[1])
	  .attr("class", "languageText")
	  .attr("id", function(d) {
			if (stateOrDistrictOrLanguage(d) == "language") {
				return d.properties.lang_code+"Language"
			} else {
				d3.select(this).remove()
			}
	  })
      .each(function(d) {
			if (!stateOrDistrictOrLanguage(d) == "language") {
				d3.select(this).remove() // Only add this attribute if the element is a language
			}
      })
      .text(function(d) {
			if (stateOrDistrictOrLanguage(d) == "language") {
				return d.properties.lang_name;
			} else {
				d3.select(this).remove() // Only add this attribute if the element is a language
			}
		})
      .attr("text-anchor", d => typeof d.properties.lang_name != "undefined" && languages[d.properties.lang_name.toLowerCase()].text_align)
      .attr("fill", "black")

		let allLangs = []

	const coordinates = [77.69916967457782,23.389970772934166];
	const [xCoord, yCoord] = projection(coordinates);

	// Add a listener to toggle the language display when a language is hovered on the map
	document.querySelectorAll(".language").
				forEach(function(element) {
						element.addEventListener("mouseover", toggleLanguageDisplay);
						element.addEventListener("mouseout", toggleLanguageDisplay);
				});

	// Remove all 'g' elements that have no children (they don't have a language, translation, or romanization). This must mean they accidentally got created when I created the 'textItems' variable
	document.querySelectorAll("g").
			forEach(function(element) {
					if (element.childElementCount == 0) {
							element.remove()
					}
			});


//	svg.append("text")
//    .attr("x", xCoord)
//    .attr("y", yCoord)
//	.attr("class", "testClass")
//    .attr("text-anchor", "middle")
//    .attr("font-size", "12px")
//    .attr("fill", "black")
//    .text("Hello, Map!");

//	for (const [langId,lang] of Object.entries(languages)) {
//		let geojson = {
//		    "type": "FeatureCollection",
//		    "features": lang.districts
//		};
//	
//		let outerBound = getOuterBoundaryPolygon(geojson.features)
//		outerBound["id"] = "lang" + lang.name
//		outerBound.properties["lang_name"]= lang.name
//		outerBound.properties["lang_code"]= lang.code
//		allLangs.push(outerBound);
//
//		svg.append("path")
//	  		.datum(outerBound)
//	  		.attr("d", path)
//	  		.attr("fill", "none")
//	  		.attr("stroke", "red")
//	  		.attr("stroke-width", 2)
//	}
//	console.log(JSON.stringify(allLangs))

}

d3.json("india_with_districts_with_languages_min.json").then(drawMap)
