// ==UserScript==
// @name        Fanfiction Search Plus
// @namespace   https://greasyfork.org/users/102866
// @description Give more options to search
// @include     https://www.fanfiction.net/*
// @require     https://code.jquery.com/jquery-3.2.1.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/list.js/1.5.0/list.min.js
// @author      TiLied
// @version     0.1.00
// @grant       GM_listValues
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_deleteValue
// @require     https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @grant       GM.listValues
// @grant       GM.getValue
// @grant       GM.setValue
// @grant       GM.deleteValue
// @downloadURL none
// ==/UserScript==
var whatPage = 0,
	fanName,
	section,
	listTrue = false;
const oneSecond = 1000,
	oneDay = oneSecond * 60 * 60 * 24,
	oneWeek = oneDay * 7,
	oneMonth = oneWeek * 4,
	mRatingAndUpTime = "?&srt=1&r=10";
//prefs
var ff = {},
	debug = false;
/**
* ENUM, BECAUSE WHY NOT ¯\_(ツ)_/¯
* SEE FUNCTION GetPage()
*/
var Page;
(function (Page)
{
	
	Page[Page["ErrorNothing"] = 0] = "ErrorNothing";
	Page[Page["front"] = 1] = "front";
	Page[Page["anime"] = 2] = "anime";
	Page[Page["book"] = 3] = "book";
	Page[Page["cartoon"] = 4] = "cartoon";
	Page[Page["comic"] = 5] = "comic";
	Page[Page["game"] = 6] = "game";
	Page[Page["misc"] = 7] = "misc";
	Page[Page["play"] = 8] = "play";
	Page[Page["movie"] = 9] = "movie";
	Page[Page["tv"] = 10] = "tv";
	Page[Page["crossover"] = 10] = "crossover";
	Page[Page["crossoverR"] = 11] = "crossoverR";
	Page[Page["ErrorNothing1"] = 100] = "ErrorNothing1";
})(Page || (Page = {}));
//Start
//Function main
void function Main()
{
	console.log("Fanfiction Search Plus v" + GM.info.script.version + " initialization");
	//Place CSS in head
	SetCSS();
	//Set settings or create
	SetSettings(function ()
	{
		//Check on what page we are and switch. Currently only on pin page
		SwitchPage();
		//Place UI Options
		//SetOption();
		console.log("Page number: " + whatPage + "/" + Page[whatPage] + " page");
	});
}();
//Function main
//End
//Start
//Functions GM_VALUE
async function SetSettings(callBack)
{
	//DeleteValues("all");
	//THIS IS ABOUT fanfiction
	if (HasValue("fsp_ff", JSON.stringify(ff)))
	{
		ff = JSON.parse(await GM.getValue("fsp_ff"));
		console.log(ff);
		SetFFObj();
	}
	//Console log prefs with value
	console.log("*prefs:");
	console.log("*-----*");
	var vals = await GM.listValues();
	//Find out that var in for block is not local... Seriously js?
	for (let i = 0; i < vals.length; i++)
	{
		console.log("*" + vals[i] + ":" + await GM.getValue(vals[i]));
	}
	console.log("*-----*");
	callBack();
}
//Check if value exists or not.  optValue = Optional
async function HasValue(nameVal, optValue)
{
	var vals = await GM.listValues();
	if (vals.length === 0)
	{
		if (optValue !== undefined)
		{
			GM.setValue(nameVal, optValue);
			return true;
		} else
		{
			return false;
		}
	}
	if (typeof nameVal !== "string")
	{
		return alert("name of value: '" + nameVal + "' are not string");
	}
	for (let i = 0; i < vals.length; i++)
	{
		if (vals[i] === nameVal)
		{
			return true;
		}
	}
	if (optValue !== undefined)
	{
		GM.setValue(nameVal, optValue);
		return true;
	} else
	{
		return false;
	}
}
//Delete Values
async function DeleteValues(nameVal)
{
	var vals = await GM.listValues();
	if (vals.length === 0 || typeof nameVal !== "string")
	{
		return;
	}
	switch (nameVal)
	{
		case "all":
			for (let i = 0; i < vals.length; i++)
			{
				GM.deleteValue(vals[i]);
			}
			break;
		case "old":
			for (let i = 0; i < vals.length; i++)
			{
				if (vals[i] === "debug" || vals[i] === "debugA")
				{
					GM.deleteValue(vals[i]);
				}
			}
			break;
		default:
			for (let i = 0; i < vals.length; i++)
			{
				if (vals[i] === nameVal)
				{
					GM.deleteValue(nameVal);
				}
			}
			break;
	}
}
///Update gm value what:"cache","options"
function UpdateGM(what)
{
	var gmff;
	switch (what)
	{
		case "ff":
			gmff = JSON.stringify(ff);
			GM.setValue("fsp_ff", gmff);
			break;
		case "options":
			gmVal = JSON.stringify(options);
			GM_setValue("imdbe_options", gmVal);
			break;
		default:
			alert("fun:UpdateGM(" + what + "). default switch");
			break;
	}
}
//Functions GM_VALUE
//End
//Start
//Functions create object fanfiction and cache
function SetFFObj()
{
	//Version
	if (typeof ff.version === "undefined")
	{
		ff.version = GM.info.script.version;
		version = ff.version;
	} else
	{
		version = ff.version;
		if (version !== GM.info.script.version)
		{
			ff.version = GM.info.script.version;
			version = ff.version;
		}
	}
	//Fetch
	if (typeof ff.fetch === "undefined")
	{
		ff.fetch = false;
		//version = ff.version;
	} else
	{
		//version = ff.version;
		//if (version !== GM.info.script.version)
		//{
		//	ff.version = GM.info.script.version;
		//	version = ff.version;
		//}
	}
	//Fanfiction
	if (typeof ff.fanfiction === "undefined")
	{
		ff.fanfiction = {};
		//fanfiction = options.additionalRatings;
	} else
	{
		//if (options.additionalRatings["kinopoisk"] === undefined) { options.additionalRatings[kinopoisk] = false; }
		//if (options.additionalRatings["rottenTomatoes"] === undefined) { options.additionalRatings[rottenTomatoes] = false; }
		//additionalRatings = options.additionalRatings;
	}
	if (debug) console.log(ff);
}
//Functions create object option and cache
//End
//Start
//Functions Get on what page are we and switch
function SwitchPage()
{
	switch (GetPage(document.URL))
	{
		case 1:
			console.log("front");
			break;
		case 2:
			section = Page[whatPage];
			SetUpForAnime(document.URL);
			break;
		case 3:
			section = Page[whatPage];
			SetUpForBook(document.URL);
			break;
		case 4:
			section = Page[whatPage];
			SetUpForCartoon(document.URL);
			break;
		case 5:
			section = Page[whatPage];
			SetUpForComic(document.URL);
			break;
		case 6:
			section = Page[whatPage];
			SetUpForGame(document.URL);
			break;
		case 7:
			section = Page[whatPage];
			SetUpForMisc(document.URL);
			break;
		case 8:
			section = Page[whatPage];
			SetUpForPlay(document.URL);
			break;
		case 9:
			section = Page[whatPage];
			SetUpForMovie(document.URL);
			break;
		case 10:
			section = Page[whatPage];
			SetUpForTv(document.URL);
			break;
		default:
			break;
	}
}
//On what page are we?
function GetPage(url)
{
	/*
	1-front page
	2-anime page
	3-book page
	4-cartoon page
	5-comic page
	6-game page
	7-misc page
	8-play page
	9-movie page
	10-tv page
	11-Crossover/ page
	12-Crossover/ page
	13-Crossover/ page
	14-Crossover/ page
	15-Crossover/ page
	100-anything else
	*/
	try
	{
		if (document.location.pathname === "/")
		{
			whatPage = 1;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/anime/i))
		{
			whatPage = 2;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/book/i))
		{
			whatPage = 3;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/cartoon/i))
		{
			whatPage = 4;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/comic/i))
		{
			whatPage = 5;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/game/i))
		{
			whatPage = 6;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/misc/i))
		{
			whatPage = 7;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/play/i))
		{
			whatPage = 8;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/movie/i))
		{
			whatPage = 9;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/tv/i))
		{
			whatPage = 10;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/crossover/i))
		{
			whatPage = 11;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/crossover/i))
		{
			whatPage = 12;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/crossover/i))
		{
			whatPage = 13;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/crossover/i))
		{
			whatPage = 14;
		} else if (url.match(/https:\/\/www\.fanfiction\.net\/crossover/i))
		{
			whatPage = 15;
		} else 
		{
			whatPage = 100;
		}
	} catch (e) { console.og(e); }
	return whatPage;
}
//Functions Get on what page are we and switch
//End
//-------------------------
//SET UP STUFF BELOW
//-------------------------
function SetUpForAnime(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/anime\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForBook(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/book\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForCartoon(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/cartoon\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForComic(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/comic\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForGame(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/game\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForMisc(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/misc\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForPlay(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/play\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForMovie(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/movie\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
function SetUpForTv(url)
{
	try
	{
		if (typeof ff.fanfiction[section] === "undefined")
		{
			ff.fanfiction[section] = {};
			//Update GM TODO
		}
		fanName = url.match(/tv\/(\S+)\//)[1]; //TODO!!!!!!!!!!!!!!!!!!!!
		if (debug) console.log(fanName);
		if (typeof ff.fanfiction[section][fanName] === "undefined" || ff.fanfiction[section][fanName].length === 0)
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			ff.fanfiction[section][fanName] = [];
			UI("first");
		} else
		{
			if (ff.fetch)
			{
				setTimeout(FetchFics, 1000);
			}
			UI("normal");
			//TODO check updates and etc 
		}
		//console.log($("center:first > a:last-child").trigger());
		//ParseFic($(".z-list")[4]);
	} catch (e) { console.error(e); }
}
//-------------------------
//CORE STUFF BELOW
//-------------------------
//Start
//Function parse fic
function ParseFic(div)
{
	try
	{
		var tempFic = {},
			tempSplit,
			indexes = [];
		tempFic.href = "https://www.fanfiction.net" + $(div.firstChild).attr("href");
		tempFic.id = $(div.firstChild).attr("href").split("/")[2];
		tempFic.image = $(div.firstChild.firstChild).attr("src");
		tempFic.author = $(div).find("a").filter(function ()
		{
			var str = $(this).attr("href");
			if (str.includes("/u/"))
			{
				return this;
			}
		}).text();
		tempFic.authorUrl = "https://www.fanfiction.net" + $(div).find("a").filter(function ()
		{
			var str = $(this).attr("href");
			if (str.includes("/u/"))
			{
				return this;
			}
		}).attr("href");
		tempFic.title = $(div.firstChild.childNodes[1]).text();
		
		tempFic.summary = $(div).find(".z-indent").contents().filter(function ()
		{
			return this.nodeType === 3;
		})[0].nodeValue;
		tempSplit = $(div).find(".z-indent > .z-padtop2").html().split(" - ");
		if(debug) console.log(tempSplit);
		tempFic.rated = $.trim(tempSplit[0].substr(tempSplit[0].indexOf(":")).substring(2));
		tempFic.language = $.trim(tempSplit[1]);
		if (tempSplit[3].match("Chapters"))
		{
			if (tempSplit[2].match("/"))
				tempFic.gernes = $.trim(tempSplit[2]).split("/");
			else
				tempFic.gernes = $.trim(tempSplit[2]);
			tempFic.chapters = Number($.trim(tempSplit[3].substr(tempSplit[3].indexOf(":")).substring(2).split(",").join("")));
			tempFic.words = Number($.trim(tempSplit[4].substr(tempSplit[4].indexOf(":")).substring(2).split(",").join("")));
		} else
		{
			tempFic.gernes = "none";
			tempFic.chapters = Number($.trim(tempSplit[2].substr(tempSplit[2].indexOf(":")).substring(2).split(",").join("")));
			tempFic.words = Number($.trim(tempSplit[3].substr(tempSplit[3].indexOf(":")).substring(2).split(",").join("")));
		}
		for (let i = 0; i < tempSplit.length; i++)
		{
			if (tempSplit[i].match("Reviews"))
				tempFic.reviews = Number($.trim(tempSplit[i].substr(tempSplit[i].indexOf(":")).substring(2).split(",").join("")));
			if (tempSplit[i].match("Favs"))
				tempFic.favs = Number($.trim(tempSplit[i].substr(tempSplit[i].indexOf(":")).substring(2).split(",").join("")));
			if (tempSplit[i].match("Follows"))
				tempFic.follows = Number($.trim(tempSplit[i].substr(tempSplit[i].indexOf(":")).substring(2).split(",").join("")));
			if (tempSplit[i].match("Published"))
				tempFic.published = Number($.trim(tempSplit[i].split('"')[1]));
			if (tempSplit[i].match("Updated"))
				tempFic.updated = Number($.trim(tempSplit[i].split('"')[1]));
			if (tempSplit[i].match("Complete"))
				tempFic.complete = true;
		}
		if (typeof tempFic.reviews === "undefined")
			tempFic.reviews = 0;
		if (typeof tempFic.favs === "undefined")
			tempFic.favs = 0;
		if (typeof tempFic.follows === "undefined")
			tempFic.follows = 0;
		if (typeof tempFic.updated === "undefined")
			tempFic.updated = 0;
			//tempFic.updated = "" | "none";
		if (typeof tempFic.complete === "undefined")
			tempFic.complete = false;
		if (tempFic.complete)
		{
			if (!tempSplit[tempSplit.length - 2].match("Published"))
				if (!tempSplit[tempSplit.length - 2].match("Updated"))
					tempFic.characters = tempSplit[tempSplit.length - 2].split(", ");
			if (tempSplit[tempSplit.length - 2].match(/]/))
			{
				tempFic.characters = tempSplit[tempSplit.length - 2].replace(/]/, ",").split(", ");
				let temp = tempSplit[tempSplit.length - 2],
					arr = [];
				if(debug) console.log(temp);
				for (let x = 0; x < temp.length; x++)
					if (temp[x] === "[" || temp[x] === "]")
						indexes.push(x);
				if (debug) console.log(indexes);
				if (indexes.length > 2)
				{
					//TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					arr.push(temp.slice(indexes[0] + 1, indexes[1]).split(", "));
					arr.push(temp.slice(indexes[2] + 1, indexes[3]).split(", "));
					if (debug) console.log(arr);
					tempFic.relationships = arr;
				} else
				{
					temp = temp.substring(temp.indexOf("[") + 1, temp.indexOf("]"));
					if (debug) console.log(temp);
					tempFic.relationships = [temp.split(", ")];
				}
			}
		} else
		{
			if (!tempSplit[tempSplit.length - 1].match("Published"))
				if (!tempSplit[tempSplit.length - 1].match("Updated"))
					tempFic.characters = tempSplit[tempSplit.length - 1].split(", ");
			if (tempSplit[tempSplit.length - 1].match(/]/))
			{
				tempFic.characters = tempSplit[tempSplit.length - 1].replace(/]/, ",").split(", ");
				let temp = tempSplit[tempSplit.length - 1],
					arr = [];
				if (debug) console.log(temp);
				for (let x = 0; x < temp.length; x++)
					if (temp[x] === "[" || temp[x] === "]")
						indexes.push(x);
				if (indexes.length > 2)
				{
					//TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					arr.push(temp.slice(indexes[0] + 1, indexes[1]).split(", "));
					arr.push(temp.slice(indexes[2] + 1, indexes[3]).split(", "));
					tempFic.relationships = arr;
				} else
				{
					temp = temp.substring(temp.indexOf("[") + 1, temp.indexOf("]"));
					if (debug) console.log(temp);
					tempFic.relationships = [temp.split(", ")];
				}
			}
		}
		if (typeof tempFic.characters === "undefined")
			tempFic.characters = "none";
			//tempFic.characters = [] | "none";	//none or all??? TODO
		if (typeof tempFic.relationships === "undefined")
			tempFic.relationships = "none";
			//tempFic.relationships = [] | "none";
		if (debug) console.log(tempFic);
		return tempFic;
	} catch (e) { console.error(e); }
}
//Function parse fic
//End
//Start
//Function fetch fics
async function FetchFics()
{
	try
	{
		var zlist = $(".z-list"),
			last,
			parser = new DOMParser();
		for (let i = 0; i < zlist.length; i++)
		{
			ff.fanfiction[section][fanName].push(ParseFic(zlist[i]));
		}
		UI("upFetchCount");
		
		setTimeout(async function ()
		{
			last = $("center:first > a:last-child").prev().attr("href");
			last = Number(last.substr(last.indexOf("p=") + 2));
			if (debug) console.log(last);
			for (let i = 2; i <= last; i++)
			{
				if (debug) console.log("https://www.fanfiction.net/" + section + "/" + fanName + "/" + mRatingAndUpTime + "&p=" + i);
				await $.get("https://www.fanfiction.net/" + section + "/" + fanName + "/" + mRatingAndUpTime + "&p=" + i, function (data)
				{
					var doc = parser.parseFromString(data, "text/html"),
						z = $(doc).find(".z-list");
					if (debug) console.log(doc);
					if (debug) console.log(z);
					for (let x = 0; x < z.length; x++)
					{
						ff.fanfiction[section][fanName].push(ParseFic(z[x]));
					}
					UI("upFetchCount");
				})
					.fail(function ()
					{
						alert("error: ajax/" + i + "-page number/" + fanName + " fandom");
					});
			}
			ff.fetch = false;
			UpdateGM("ff");
			alert("ITS DONE!!!");
			window.location.href = "https://www.fanfiction.net/" + section + "/" + fanName + "/";
		}, 250);
		//Get to the next page and thats go on
	} catch (e) { console.error(e); }
}
//Function fetch fics
//End
//Start
//Function Search Filter Sort fics
function SearchFilterSort()
{
	try
	{
		var options = {
			valueNames:
			[
				'fsp_title',
				{ name: 'fsp_titleh', attr: 'href' },
				{ name: 'fsp_image', attr: 'src' },
				'fsp_author',
				{ name: 'fsp_authorh', attr: 'href' },
				'fsp_summary',
				'fsp_rated',
				'fsp_lag',
				'fsp_chapters',
				'fsp_words',
				'fsp_reviews',
				'fsp_favs',
				'fsp_follows',
				'fsp_published',
				{ name: 'fsp_publishedRaw', attr: 'data-xutime' },
				'fsp_updated',
				{ name: 'fsp_updatedRaw', attr: 'data-xutime' },
				'fsp_complete',
				'fsp_characters',
				'fsp_relationships',
				'fsp_Id'
			],
			page: 20,
			pagination: true,
			item: '
\
			
\
			
![]()
\
			by 
\
			
\
			
Rated:\
			- 
Language:\
			- 
Chapters:\
			- 
Words:\
			- 
Reviews:\
			- 
Favs:\
			- 
Follows:\
			- 
Published:\
			- 
Updated:\
			- 
Complete:\
			- 
Characters:\
			- 
Relationships:\\
			- 
Id:'
		};
		
		var fics = new List('fsp_main', options);
		//console.log(ff.fanfiction[section][fanName]);
		for (let i = 0; i < ff.fanfiction[section][fanName].length; i++)
		{
			if (ff.fanfiction[section][fanName][i]["updated"] === 0)
			{
				fics.add({
					fsp_title: ff.fanfiction[section][fanName][i]["title"],
					fsp_titleh: ff.fanfiction[section][fanName][i]["href"],
					fsp_image: ff.fanfiction[section][fanName][i]["image"],
					fsp_author: ff.fanfiction[section][fanName][i]["author"],
					fsp_authorh: ff.fanfiction[section][fanName][i]["authorUrl"],
					fsp_summary: ff.fanfiction[section][fanName][i]["summary"],
					fsp_rated: ff.fanfiction[section][fanName][i]["rated"],
					fsp_lag: ff.fanfiction[section][fanName][i]["language"],
					fsp_chapters: ff.fanfiction[section][fanName][i]["chapters"],
					fsp_words: ff.fanfiction[section][fanName][i]["words"],
					fsp_reviews: ff.fanfiction[section][fanName][i]["reviews"],
					fsp_favs: ff.fanfiction[section][fanName][i]["favs"],
					fsp_follows: ff.fanfiction[section][fanName][i]["follows"],
					fsp_published: Intl.DateTimeFormat(undefined, { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(ff.fanfiction[section][fanName][i]["published"] * 1000)),
					fsp_publishedRaw: ff.fanfiction[section][fanName][i]["published"],
					fsp_updated: 0,
					fsp_updatedRaw: ff.fanfiction[section][fanName][i]["updated"],
					fsp_complete: ff.fanfiction[section][fanName][i]["complete"],
					fsp_characters: ff.fanfiction[section][fanName][i]["characters"],
					fsp_relationships: ff.fanfiction[section][fanName][i]["relationships"],
					fsp_Id: ff.fanfiction[section][fanName][i]["id"]
				});
			} else
			{
				fics.add({
					fsp_title: ff.fanfiction[section][fanName][i]["title"],
					fsp_titleh: ff.fanfiction[section][fanName][i]["href"],
					fsp_image: ff.fanfiction[section][fanName][i]["image"],
					fsp_author: ff.fanfiction[section][fanName][i]["author"],
					fsp_authorh: ff.fanfiction[section][fanName][i]["authorUrl"],
					fsp_summary: ff.fanfiction[section][fanName][i]["summary"],
					fsp_rated: ff.fanfiction[section][fanName][i]["rated"],
					fsp_lag: ff.fanfiction[section][fanName][i]["language"],
					fsp_chapters: ff.fanfiction[section][fanName][i]["chapters"],
					fsp_words: ff.fanfiction[section][fanName][i]["words"],
					fsp_reviews: ff.fanfiction[section][fanName][i]["reviews"],
					fsp_favs: ff.fanfiction[section][fanName][i]["favs"],
					fsp_follows: ff.fanfiction[section][fanName][i]["follows"],
					fsp_published: Intl.DateTimeFormat(undefined, { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(ff.fanfiction[section][fanName][i]["published"] * 1000)),
					fsp_publishedRaw: ff.fanfiction[section][fanName][i]["published"],
					fsp_updated: Intl.DateTimeFormat(undefined, { year: 'numeric', month: 'short', day: 'numeric' }).format(new Date(ff.fanfiction[section][fanName][i]["updated"] * 1000)),
					fsp_updatedRaw: ff.fanfiction[section][fanName][i]["updated"],
					fsp_complete: ff.fanfiction[section][fanName][i]["complete"],
					fsp_characters: ff.fanfiction[section][fanName][i]["characters"],
					fsp_relationships: ff.fanfiction[section][fanName][i]["relationships"],
					fsp_Id: ff.fanfiction[section][fanName][i]["id"]
				});
			}
		}
		//$('.search').on('keyup', function ()
		//{
		//	var searchString = $(this).val();
		//	fics.search(searchStrisng, ['fsp_words']);
		//});
		
		$("#fsp_resultCount").text(fics.size());
		$('.fsp_searchAuthor').keyup(function ()
		{
			var searchString = $(this).val();
			fics.search(searchString, ['fsp_author']);
		});
		$('.fsp_searchTitle').keyup(function ()
		{
			var searchString = $(this).val();
			fics.search(searchString, ['fsp_title']);
		});
		fics.on("updated", function ()
		{
			$(".fsp_list").unhighlight();
			var search = $(".search").val();
			var words = search.split(" ");
			$(".fsp_list").highlight(words);
			$("#fsp_resultCount").text(fics.matchingItems.length);
		}); // trigger
		
		$('.fsp_filterChapters, .fsp_filterWords, .fsp_filterReviews, .fsp_filterFavs, .fsp_filterFollows, .fsp_filterPublishedA, .fsp_filterPublishedB, .fsp_filterUpdatedA, .fsp_filterUpdatedB, .fsp_filterCharacters, .fsp_filterRelationships').on('keyup change', function ()
		{
			var number = [];
			var raw = [$(".fsp_filterChapters").val(), $(".fsp_filterWords").val(), $(".fsp_filterReviews").val(), $(".fsp_filterFavs").val(), $(".fsp_filterFollows").val(), $(".fsp_filterPublishedA").val(), $(".fsp_filterPublishedB").val(), $(".fsp_filterUpdatedA").val(), $(".fsp_filterUpdatedB").val(), $(".fsp_filterCharacters").val(), $(".fsp_filterRelationships").val()];
			var fsp = ["fsp_chapters", "fsp_words", "fsp_reviews", "fsp_favs", "fsp_follows", "fsp_publishedRaw", "fsp_publishedRaw", "fsp_updatedRaw", "fsp_updatedRaw", "fsp_characters", "fsp_relationships"];
			var im = [];
			if(debug) console.log(raw);
			for (let i = 0; i < raw.length; i++)
			{
				if (raw[i].match(">"))
				{
					number[i] = Number(raw[i].substr(1));
				} else if (raw[i].match("<"))
				{
					number[i] = Number(raw[i].substr(1));
				} else { number[i] = Number(raw[i]); }
				if (i >= 5 && i < 9)
				{
					if (raw[i] === "")
						number[i] = 0;
					else
						number[i] = new Date(raw[i]).getTime() / 1000;
				} else if (i === 9)
				{
					if (raw[i] === "")
						number[i] = 0;
					else
						number[i] = raw[i].split(",");
				} else if (i === 10)
				{
					if (raw[i] === "")
						number[i] = 0;
					else
						number[i] = raw[i].split(",");
				}
			}
			if (debug) console.log(number);
			fics.filter(function (item)
			{
				for (let i = 0; i < raw.length; i++)
				{
					if (raw[i] === "") continue;
					if (i >= 5 && i < 9)
					{
						if (!IsEven(i))
						{
							if (item.values()[fsp[i]] >= number[i])
							{
								im.push(true);
							}
							else
							{
								return false;
							}
						} else
						{
							if (item.values()[fsp[i]] <= number[i])
							{
								im.push(true);
							}
							else
							{
								return false;
							}
						}
					} else if (i === 9)
					{
						if (item.values()[fsp[i]] === "none")
							if (number[i] !== "none")
								return false;
							else
								return true;
						let temp = item.values()[fsp[i]];
						let yn = [];
						let c = 0;
						for (let j = 0; j < temp.length; j++)
						{
							for (let y = 0; y < number[i].length; y++)
							{
								if (temp[j].toUpperCase().match($.trim(number[i][y].toUpperCase())))
								{
									yn[j] = true;
									c++;
									break;
								}
								else
								{
									yn[j] = false;
								}
							}
						}
						if (c >= number[i].length)
							return true;
						else
							return false;
						if (yn.every(e => e === false))
							return false;
						else
							return true;
					} else if (i === 10)
					{
						if (item.values()[fsp[i]] === "none")
							if (number[i] !== "none")
								return false;
							else
								return true;
						let temp = item.values()[fsp[i]].slice(0);
						let tempR = temp.slice(0);
						for (let a = 0; a < temp.length; a++)
						{
							temp[a] = temp[a].join("/");
						}
						for (let a = 0; a < tempR.length; a++)
						{
							tempR[a] = tempR[a].reverse().join("/");
						}
						//console.log(temp);
						//console.log(tempR);
						let yn = [];
						let c = 0;
						for (let j = 0; j < temp.length; j++)
						{
							for (let y = 0; y < number[i].length; y++)
							{
								if (temp[j].toUpperCase().match($.trim(number[i][y].toUpperCase())) || tempR[j].toUpperCase().match($.trim(number[i][y].toUpperCase())))
								{
									yn[j] = true;
									c++;
									break;
								}
								else
								{
									yn[j] = false;
								}
							}
						}
						if (c >= number[i].length)
							return true;
						else
							return false;
						if (yn.every(e => e === false))
							return false;
						else
							return true;
					} else
					{
						if (raw[i].match(">"))
						{
							if (item.values()[fsp[i]] >= number[i])
							{
								im.push(true);
							}
							else
							{
								return false;
							}
						} else if (raw[i].match("<"))
						{
							if (item.values()[fsp[i]] <= number[i])
								im.push(true);
							else
								return false;
						} else if (item.values()[fsp[i]] === number[i])
						{
							im.push(true);
						} else
							return false;
					}
				}
				if (im.every(e => e === true))
					return true;
				else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw.every(e => e === ""))
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		/*
		$('.fsp_filterPublishedA, .fsp_filterPublishedB, .fsp_filterUpdatedA, .fsp_filterUpdatedB').on('change', function ()
		{
			var number = [];
			var raw = [$(".fsp_filterPublishedA").val(), $(".fsp_filterPublishedB").val(), $(".fsp_filterUpdatedA").val(), $(".fsp_filterUpdatedB").val()];
			var fsp = ["fsp_publishedRaw", "fsp_publishedRaw", "fsp_updatedRaw", "fsp_updatedRaw"];
			var im = [];
			for (let i = 0; i < raw.length; i++)
			{
				number[i] = new Date(raw[i]).getTime() / 1000;
			}
			fics.filter(function (item)
			{
				for (let i = 0; i < raw.length; i++)
				{
					if (raw[i] === "") continue;
					if (IsEven(i))
					{
						if (item.values()[fsp[i]] >= number[i])
						{
							im.push(true);
						}
						else
						{
							return false;
						}
					} else
					{
						if (item.values()[fsp[i]] <= number[i])
						{
							im.push(true);
						}
						else
						{
							return false;
						}
					}
					
				}
				if (im.every(e => e === true))
					return true;
				else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw.every(e => e === ""))
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		*/
		/*
		$('.fsp_filterChapters').on('keyup', function ()
		{
			var number;
			var raw = $(this).val();
			if (raw.match(">"))
			{
				number = raw.substr(1);
			} else if (raw.match("<"))
			{
				number = raw.substr(1);
			} else { number = raw; }
			fics.filter(function (item)
			{
				if (raw.match(">"))
				{
					if (item.values().fsp_chapters >= number)
						return true;
					else
						return false;
				} else if (raw.match("<"))
				{
					if (item.values().fsp_chapters <= number)
						return true;
					else
						return false;
				} else if (item.values().fsp_chapters === number)
				{
					return true;
				} else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw === "")
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		$('.fsp_filterWords').on('keyup', function ()
		{
			var number;
			var raw = $(this).val();
			
			if (raw.match(">"))
			{
				number = raw.substr(1);
			} else if (raw.match("<"))
			{
				number = raw.substr(1);
			} else { number = raw; }
			fics.filter(function (item)
			{
				if (raw.match(">"))
				{
					if (item.values().fsp_words >= number)
						return true;
					else
						return false;
				} else if (raw.match("<"))
				{
					if (item.values().fsp_words <= number)
						return true;
					else
						return false;
				} else if (item.values().fsp_words === number)
				{
					return true;
				} else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw === "")
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		$('.fsp_filterReviews').on('keyup', function ()
		{
			var number;
			var raw = $(this).val();
			if (raw.match(">"))
			{
				number = raw.substr(1);
			} else if (raw.match("<"))
			{
				number = raw.substr(1);
			} else { number = raw; }
			fics.filter(function (item)
			{
				if (raw.match(">"))
				{
					if (item.values().fsp_reviews >= number)
						return true;
					else
						return false;
				} else if (raw.match("<"))
				{
					if (item.values().fsp_reviews <= number)
						return true;
					else
						return false;
				} else if (item.values().fsp_reviews === number)
				{
					return true;
				} else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw === "")
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		$('.fsp_filterFavs').on('keyup', function ()
		{
			var number;
			var raw = $(this).val();
			if (raw.match(">"))
			{
				number = raw.substr(1);
			} else if (raw.match("<"))
			{
				number = raw.substr(1);
			} else { number = raw; }
			fics.filter(function (item)
			{
				if (raw.match(">"))
				{
					if (item.values().fsp_favs >= number)
						return true;
					else
						return false;
				} else if (raw.match("<"))
				{
					if (item.values().fsp_favs <= number)
						return true;
					else
						return false;
				} else if (item.values().fsp_favs === number)
				{
					return true;
				} else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw === "")
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		$('.fsp_filterFollows').on('keyup', function ()
		{
			var number;
			var raw = $(this).val();
			if (raw.match(">"))
			{
				number = raw.substr(1);
			} else if (raw.match("<"))
			{
				number = raw.substr(1);
			} else { number = raw; }
			fics.filter(function (item)
			{
				if (raw.match(">"))
				{
					if (item.values().fsp_follows >= number)
						return true;
					else
						return false;
				} else if (raw.match("<"))
				{
					if (item.values().fsp_follows <= number)
						return true;
					else
						return false;
				} else if (item.values().fsp_follows === number)
				{
					return true;
				} else
					return false;
			}); // Only items with id > 1 are shown in list
			if (raw === "")
			{
				fics.filter();
			}
			$("#fsp_resultCount").text(fics.matchingItems.length);
		});
		*/
	} catch (e) { console.error(e); }
}
//Function Search Filter Sort fics
//End
//-------------------------
//UI/Events STUFF BELOW
//-------------------------
//Start
//Function UI add 
function UI(what)
{
	try
	{
		var a,
			s;
		switch (what)
		{
			case "first":
				a = $("
").text("Fetch fanfics");
				$("#content_wrapper_inner > span:first").prepend("	|	");
				$("#content_wrapper_inner > span:first").prepend("
" + ff.fanfiction[section][fanName].length + "");
				$("#content_wrapper_inner > span:first").prepend("	|	");
				$("#content_wrapper_inner > span:first").prepend(a);
				SetEvents(what, a);
				break;
			case "normal":
				var div = $("
").html('
\
					
\
					
\
					\
					\
					\
					\
					\
					\
					\
					\
					\
					\
					\
					\
					
\
					
\
					
\
					\
					
\
					
\
					
\
					\