{
	"translatorID": "6c61897b-ca44-4ce6-87c1-2da68b44e6f7",
	"label": "Summon 2",
	"creator": "Caistarrin Mystical and Aurimas Vinckevicius",
	"target": "^https?://([^/]+\\.)?summon\\.serialssolutions\\.com/",
	"minVersion": "4.0",
	"maxVersion": "",
	"priority": 150,
	"inRepository": true,
	"translatorType": 4,
	"browserSupport": "gcsib",
	"lastUpdated": "2017-06-24 21:11:06"
}

/*
   Summon 2.0 Translator
   Copyright (C) 2014 ProQuest LLC
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

function detectWeb(doc, url) {
	var results = doc.getElementById('results');
	var displayMultiple = false;
	if (results) {
		var ul = results.firstElementChild.firstElementChild;
		if (ul) {
			// This is currently broken in Zotero.
			// Scrolling down one page ends up triggering Page Modified event
			// 111 times and makes the page unusable after a while.
			//Zotero.monitorDOMChanges(ul, {childList: true});
			
			// temporary hack to display multiples
			displayMultiple = true;
		}
	}
	
	var detailPage = doc.getElementsByClassName('detailPage')[0];
	if (detailPage) {
		// Changes from visible to not by adding class ng-hide
		Zotero.monitorDOMChanges(detailPage, {attributes: true, attributeFiler: ['class']});
		if (detailPage.offsetHeight) {
			// Visible details page
			var id = getIDFromUrl(url);
			if (id) return 'book';
		}
	}
	
	if (getSearchResults(doc, true) || displayMultiple) {
		return "multiple";
	}
}

function getIDFromUrl(url) {
	var m = url.match(/[&?]id=([^&#]+)/);
	return m && m[1];
}

function getSearchResults(doc, checkOnly) {
	var results = doc.getElementById('results');
	if (!results) return false;
	
	var titles = results.getElementsByClassName('customPrimaryLinkContainer');
	var items = {}, found = false;
	var numRollups = 0;
	for (var i=0; i<titles.length; i++) {
		var isRollup = !!ZU.xpath(titles[i], './ancestor::div[contains(@class, "rollup")]').length;
		
		// That class gets reused a bit
		if (!isRollup && titles[i].nodeName.toUpperCase() != 'H1') continue;
		
		var index;
		if (isRollup) {
			index = 'r' + numRollups;
			numRollups++;
		} else {
			index = i - numRollups;
		}
		
		var title = titles[i].getElementsByTagName('a')[0];
		if (title) title = ZU.trimInternal(title.textContent);
		
		if (!title) continue;
		
		if (checkOnly) return true;
		found = true;
		items['_' + index] = title;
	}
	
	return found ? items : false;
}

function doWeb(doc, url) {
	var dbName = ZU.xpath(doc, '//div[contains(@class, "header")]//img[contains(@class, "logo")]/@alt')[0];
	if (dbName) dbName = dbName.value;
	
	if (detectWeb(doc, url) == 'multiple') {
		Zotero.selectItems(getSearchResults(doc), function(items) {
			if (!items) {
				return true;
			}
			
			var indexes = []
			for (var item in items) {
				indexes.push(item.substr(1));
			}
			
			fetchData(getApiData(doc, url, indexes), dbName)
		});
	} else {
		var id = getIDFromUrl(url);
		var url = '/api/search?fids=' + encodeURIComponent(id);
		fetchData({urlSet: [url], indexBlocks: { 1: ['0'] }}, dbName);
	}
}

function fetchData(apiData, dbName) {
	var documents = [];
	ZU.doGet(apiData.urlSet, function (text, _, chunkUrl) {
			var obj = JSON.parse(text);
			var page = chunkUrl.match(/[?&]pn=(\d+)/);
			if (page) {
				page = page[1];
			} else if (/[?&]fids=/.test(chunkUrl)) {
				// For single pages
				page = 1;
			}
			
			var indexes = apiData.indexBlocks[page];
			
			for (var j = 0; j < indexes.length; j++) {
				var i = indexes[j];
				if (i.charAt(0) == 'r') {
					// Rollup. Drop 'r' for actual index
					documents.push(obj.rollups.newspaper.documents[i.substr(1)]);
				}
				else {
					documents.push(obj.documents[i]);
				}
			}
		},
		function () { // All done
			// Grab database name for Library Catalog field
			getRefData(documents, dbName);
		}
	);
}

var pageSize = 10; // Number of results to fetch per page
function getApiData(doc, url, indexes) {
	url = doc.location.href;
	//Z.debug(url)
	var urlArray = url.split('?');
	var apiURL = '/api/search?'
		+ urlArray.pop().replace(/(^|&)fvf=([^&#]*)/, function(m, sep, fvf) {
			return sep + 'fvf[]=' + fvf.replace(/\||%7c/gi, '&fvf[]=');
		})
		+ '&ps=' + pageSize;
	
	// Split up selected indeces into blocks set by pageSize then fetch each block
	// independently and concatenate them later
	var urlSet = [];
	var indexBlocks = {};
	for (var i = 0; i < indexes.length; i++) {
		var page, // Page number for given index (these don't have to end up continuous). 1 based
			pageIndex = indexes[i]; // Item index in a given page. 0 based

		if (pageIndex.charAt(0) == 'r') {
			// All rollups are on first page
			page = 1;
		} else {
			pageIndex *= 1; // convert to integer from string
			page = Math.ceil((pageIndex + 1) / pageSize); // +1 because 0 based
			pageIndex %= pageSize;
		}
		
		if (!indexBlocks[page]) {
			// New set
			indexBlocks[page] = [];
			urlSet.push(apiURL + "&pn=" + page);
		}
		
		indexBlocks[page].push('' + pageIndex); // make sure it's string so it's easier to check for 'r' later
	}
	
	return {"urlSet": urlSet, "indexBlocks": indexBlocks};
}

function getRefData(documents, uniName) {
	for (var i = 0; i < documents.length; i++) {
		var ref = documents[i];
		var item = new Zotero.Item(getRefType(ref));
		
		item.creators = getAuthors(ref);
		
		if (item.creators.length && ref.subtitle
			&& ref.subtitle.indexOf(item.creators[0].lastName) != -1
		) {
			item.title = ZU.cleanTags(ref.title);
			// Frequently the book's subtitle (and full title) will include the author.
			// Clean it up in those cases
			var subtitle = ZU.cleanTags(ref.subtitle)
				.replace(
					new RegExp(
						'(?:\\s*[-–—/:])?\\s*' // Possibly separated by / but account for other characters too
						+ '(?:ed(?:itor|\\.)?,?\\s+)?' // Could be an editor. Perhaps others?
						+ '(?:' + ZU.quotemeta(item.creators[0].lastName) // Not sure which one could come first
						+ (item.creators[0].firstName
							? '|' + ZU.quotemeta(item.creators[0].firstName)
							: '')
						+ ')'
						+ '.*', // Toss everything afterwards
						'i' // ignore case (mostly for editor part)
					),
					''
				);
			if (subtitle) item.title += ': ' + subtitle;
		} else {
			item.title = ZU.cleanTags(ref.full_title);
		}
		
		item.libraryCatalog = uniName + ", Summon 2.0";
		item.ISBN = ref.isbn;
		item.publisher = ref.publisher;
		item.publicationTitle = ref.publication_title;
		item.numPages = ref.page_count;
		item.tags = ref.subject_terms;
		item.series = ref.publication_series_title;
		
		if (ref.lc_call_numbers) {
			item.callNumber = ref.lc_call_numbers[0];
		}
		
		if (ref.volumes) {
			item.volume = ref.volumes[0];
		}
		
		if (ref.issues) {
			item.issue = ref.issues[0];
		}
		
		if (ref.uris) {
			item.url = ref.uris[0];
		}
		
		if (ref.languages) {
			item.language = ref.languages[0];
		}
		
		if (ref.copyrights) {
			item.rights = ref.copyrights[0];
		}
		
		if (ref.dois) {
			item.DOI = ref.dois[0];
		}
		
		if (ref.abstracts && ref.abstracts.length > 0) {
			item.abstractNote = ref.abstracts[0].abstract;
		}

		if (ref.issns) {
			item.ISSN = ref.issns[0];
		}
		else if (ref.eissns) {
			item.ISSN = ref.eissns[0];
		}

		if (ref.publication_places) {
			item.place = ref.publication_places[0];
		}
		else if (ref.dissertation_schools) {
			item.place = ref.dissertation_schools[0];
		}

		item.pages = ref.pages;
		if (!item.pages && ref.start_pages) {
			item.pages = ref.start_pages[0]
				+ (ref.end_pages && ref.end_pages.length > 0
					? "-" + ref.end_pages[0]
					: ""
				);
		}

		item.date = ref.publication_date;
		if (!item.date && ref.publication_years) {
			item.date = ref.publication_years[ref.publication_years.length - 1];
		}

		if (ref.editions && ref.editions.length > 0 
			&& ref.editions[0] != "1" 
			&& ref.editions[0].indexOf("1st") != 0 
			&& ref.editions[0].toLowerCase().indexOf("first") != 0
		) {
			// we don't care about the first edition
			item.edition = ref.editions[0];
		}
		
		item.complete();
	}
}

function getAuthors(ref) {
	var itemAuthors = [];
	var types = ['authors','corporate_authors'];
	
	for (var j=0; j<types.length; j++) {
		var isCorporate = types[j] != 'authors';
		var refAuthors = ref[types[j]];
		
		for (var i = 0; i < refAuthors.length; i++) {
			var a = refAuthors[i];
			if (a.givenname && a.surname) {
				itemAuthors.push({
					firstName: a.givenname,
					lastName: a.surname,
					creatorType: "author"
				});
			}
			else {
				var name = a.fullname || a.name || "";
				
				if (name == ref.publisher) continue;
				
				if (name.length > 0) {
					
					if (isCorporate) {
						itemAuthors.push({
							lastName: name,
							creatorType: "author",
							fieldMode: 1
						});
					}
					else {
						itemAuthors.push(ZU.cleanAuthor(name, "author", name.indexOf(',') > -1));
					}
				}
			}
		}
	}

	return itemAuthors;
}

function getRefType(ref) {
	switch(ref.content_type) {
		case "Audio Recording":
		case "Music Recording":
			return "audioRecording";
		case "Book":
		case "eBook":
			return "book";
		case "Book Chapter":
			return "bookSection";
		case "Case":
			return "case";
		case "Conference Proceeding":
			return "conferencePaper";
		case "Dissertation":
			return "thesis";
		case "Image":
		case "Photograph":
			return "artwork";
		case "Magazine":
		case "Magazine Article":
			return "magazineArticle";
		case "Manuscript":
			return "manuscript";
		case "Map":
			return "map";
		case "Newspaper Article":
		case "Newspaper":
			return "newspaperArticle";
			break;
		case "Presentation":
			return "presentation";
		case "Reference":
		case "Publication Article":
			return "encyclopediaArticle";
		case "Report":
		case "Technical Report":
		case "Data Set":
		case "Market Research":
		case "Trade Publication Article":
		case "Paper":
			return "report";
		case "Video Recording":
			return "videoRecording";
		case "Web Resource":
			return "webpage";
		case "Poem":
		case "Electronic Resource":
			if (ref.isbn) {
				return "book";
			}
			return "journalArticle";
		case "Journal Article":
		case "Journal":
		case "eJournal":
		case "Book Review":
		case "Newsletter":
		case "Archival Material":
		case "Computer File":
		case "Course Reading":
		case "Government Document":
		case "Kit":
		case "Microform":
		case "Music Score":
		case "Publication":
		case "Realia":
		case "Research Guide":
		case "Special Collection":
		case "Standard":
		case "Transcript":
		default:
			return "journalArticle";
	}
}
/** BEGIN TEST CASES **/
var testCases = [
	{
		"type": "web",
		"url": "http://dartmouth.summon.serialssolutions.com/?#!/search/document?ho=t&l=en&q=buddha&id=FETCHMERGED-dartmouth_catalog_b412227382",
		"defer": true,
		"items": [
			{
				"itemType": "book",
				"title": "Buddha",
				"creators": [
					{
						"firstName": "Osamu",
						"lastName": "Tezuka",
						"creatorType": "author"
					}
				],
				"date": "2003",
				"ISBN": "9781932234442",
				"language": "English",
				"libraryCatalog": "Dartmouth College Library, Summon 2.0",
				"numPages": "8 v.",
				"place": "New York, N.Y",
				"publisher": "Vertical",
				"attachments": [],
				"notes": [],
				"seeAlso": []
			}
		]
	},
	{
		"type": "web",
		"url": "http://dartmouth.summon.serialssolutions.com/?#!/search?ho=t&q=buddha&l=en",
		"defer": true,
		"items": "multiple"
	}
]
/** END TEST CASES **/