# Copyright 2004,2005 Pierre Martineau <pmartino@users.sourceforge.net>
# and Jouke Postma <jouke.postma@gmail.com>
# This file is part of Bibus, a bibliographic database that can
# work together with OpenOffice.org to generate bibliographic indexes.
#
# Bibus 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 2 of the License, or
# (at your option) any later version.
#
# Bibus 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 Bibus; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
#
# ISI format
# from <http://scientific.thomson.com/>
#
from __future__ import generators		# to be removed in python 2.3
import BIB

DEFAULT_ENCODING = 'latin_1'

class importRef(object):
	"""Class is iterable. Return records one by one with None for the id (first field)."""
	# conversion ISI <-> Openoffice.org Publication Type: dictionary Type[ISI name]=OpenofficeName. Only REQUIRED for NON ARTICLE
 	Type={
	'ABST':'MISC',
	'ADVS':'MISC' ,
	'ART':'MISC' ,
	'BILL':'MISC' ,
	'BOOK':'BOOK' ,
	'CASE':'MISC' ,
	'CHAP':'INBOOK' ,
	'COMP':'MISC' ,
	'CONF':'PROCEEDINGS' ,
	'C':'PROCEEDINGS' ,	# ISI Web of science
	'CTLG':'MISC' ,
	'DATA':'MISC' ,
	'ELEC':'MISC' ,
	'GEN':'MISC' ,
	'HEAR':'UNPUBLISHED' ,
	'ICOMM':'UNPUBLISHED' ,
	'INPR':'ARTICLE' ,
	'JFULL':'ARTICLE' ,
	'JOUR':'ARTICLE' ,
	'MAP':'MISC' ,
	'MGZN':'JOURNAL' ,
	'MPCT': 'MISC' ,
	'MUSIC': 'MISC' ,
	'NEWS':'JOURNAL' ,
	'PAMP': 'MISC' ,
	'PAT': 'MISC' ,
	'PCOMM':'UNPUBLISHED' ,
	'RPRT': 'TECHREPORT' ,
	'SER': 'INCOLLECTION',
	'S': 'Serial',	# ISI Web of science
	'SLIDE': 'MISC' ,
	'SOUND': 'MISC' ,
	'STAT': 'MISC' ,
	'THES': 'PHDTHESIS',
	'UNBILL': 'MISC' ,
	'UNPB':'UNPUBLISHED' ,
	'VIDEO': 'MISC'
	}
	# types in clear to put in the field howpublished
 	TypeFull={
	'ABST':'Abstract',
	'ADVS':'Audiovisual material' ,
	'ART':'Art Work' ,
	'BILL':'Bill/Resolution' ,
	'BOOK':'Book' ,
	'CASE':'Case' ,
	'CHAP':'Book chapter' ,
	'COMP':'Computer program' ,
	'CONF':'Conference proceeding' ,
	'C':'Conference proceeding' ,	# ISI Web of science
	'CTLG':'Catalog' ,
	'DATA':'Data file' ,
	'ELEC':'Electronic citation' ,
	'GEN':'Generic' ,
	'HEAR':'Hearing' ,
	'ICOMM':'Internet Communication' ,
	'INPR':'In Press' ,
	'JFULL':'Journal' ,
	'JOUR':'Journal' ,
	'J':'Journal', #jap
	'MAP':'Map' ,
	'MGZN':'Magazine article' ,
	'MPCT': 'Motion picture' ,
	'MUSIC': 'Music score' ,
	'NEWS':'Newspaper' ,
	'PAMP': 'Pamphlet' ,
	'PAT': 'Patent' ,
	'PCOMM':'Personal communication' ,
	'RPRT': 'Report' ,
	'SER': 'Serial',
	'S': 'Serial',	# ISI Web of science
	'SLIDE': 'Slide' ,
	'SOUND': 'Sound recording' ,
	'STAT': 'Statute' ,
	'THES': 'Thesis/Dissertation',
	'UNBILL': 'Unenacted bill/resolution' ,
	'UNPB':'Unpublished work' ,
	'VIDEO': 'Video recording'
	}

	def __init__(self,infile):
		self.infile = infile	# must be a file type. Need a readline() function.

	def __iter__(self):
		"""Generator of records. for record in <instance>: ...
		ISI record starts with "PT " and end with "ER"
		""" #jap
		record  = []
		line = self.infile.readline()
		while line != '':					# we should make it more robust by testing for TY as the first field
			if line.strip() != '':
				#print 'line = %r' %line
				if line[:2] != "ER":	# still not finished, #jap
					if line[:3] == "   ": # it is a continuation of the previous line #jap
						if record[-1].startswith("AU"): # Authors must be separated by ;
							record[-1] = BIB.SEP.join([record[-1],line[:-1].strip()])
						else:
							record[-1] = ' '.join([record[-1],line[:-1].strip()])
					else:
						record.append(line[:-1].strip())
				elif record != []:
					#print record
					yield self.__convertRecord(record)
					record  = []
				else:
					pass
			line = self.infile.readline()

	def __convertRecord(self,record):
		"""return a list of the record fields using
		('Identifier', 'Bibliographic_Type', 'Address', 'Annote', 'Author', 'Booktitle', 'Chapter', 'Edition', 'Editor','HowPublished', 'Institution', 'Journal', 'Month', 'Note', 'Number', 'Organizations', 'Pages', 'Publisher', 'School', 'Series', 'Title', 'Report_Type', 'Volume', 'Year', 'URL', 'Custom1', 'Custom2', 'Custom3', 'Custom4', 'Custom5', 'ISBN','Abstract')"""
		Record={}
		for line in record:
				refKey,tmpline = line[:2].strip(),line[3:].strip() #jap
				if tmpline.endswith('.'):
					tmpline = tmpline[:-1].rstrip()   	# remove final dot if present
				if Record.has_key(refKey):	   # create a new key or add to a previous one
					Record[refKey] = BIB.SEP.join([Record[refKey],tmpline])
				else:
					Record[refKey] = tmpline
		#print Record
		#
		Identifier = ''
		#
		try: Bibliographic_Type = BIB.BIBLIOGRAPHIC_TYPE[importRef.Type[Record['PT'].split(BIB.SEP)[0]]]
		except: Bibliographic_Type = BIB.BIBLIOGRAPHIC_TYPE['ARTICLE'] # default type = ARTICLE
		#
		try: Address = Record['AD']
		except KeyError: Address = ''
		#
		Annote = ''
		#
		try: Author = Record['A1'].replace('.','')		# remove all the dots
		except KeyError:
			try: Author = Record['AU'].replace('.','')	# remove all the dots
			except KeyError: Author = ''
			else:						
				# insert space after each author's initial
				# this is necessary to correctly import all author's initials
				# for Web of Science records, added by Martijn Werts
				Author_with_spaces = ''
				for indiv_author in Author.split(';'):
					# print indiv_author
					if (indiv_author.count(', ') == 1):
						indiv_author_with_spaces = indiv_author.split(', ')[0]
						indiv_author_with_spaces += ', '
						indiv_author_with_spaces += ' '.join(indiv_author.split(', ')[1])
					else:
						indiv_author_with_spaces = indiv_author 
					Author_with_spaces += (indiv_author_with_spaces+';')
				Author = Author_with_spaces.rstrip(';')
				# print '***',Author
		#
		try:
			if Bibliographic_Type != 'BOOK':
				Booktitle = Record['BT']
			else:
				raise KeyError
		except KeyError: Booktitle = ''
		#
		Chapter = ''
		#
		Edition = ''
		#
		try: Editor = Record['A3'].replace('.','')	# remove all the dots
		except KeyError: Editor = ''
		#
		HowPublished = importRef.TypeFull[Record['PT']] #jap					# we put the record type, so we now it is a patent, etc...
		#
		Institution = ''
		#
		try: Journal =  Record['J9'].title()	# should be the same than PubMed, which is our prefered format
		except KeyError:
			try: Journal =  Record['JI']	# ISO name
			except KeyError:
				try: Journal =  Record['SO']  #jap: web of science source. Full title => bibus has a table for that
				except KeyError: Journal = '' #jap
		#jap include field for abbrieviated journal titles (j1 and j9):
		#no field for this. A lookup table in bibus would be better, than including this in a field.
		#try: Journal =  Record['J9']
		#except KeyError:
		#	try: Journal =  Record['J1']
		#	except KeyError: Journal = ''
		#
		try: Month = Record['Y1'].split('/')[1]
		except KeyError:
			try: Month = Record['PY'].split('/')[1]
			except (KeyError,IndexError): Month = ''
		except IndexError:
			Month = ''
		#
		try: Note = Record['N1']
		except: Note = ''
		#
		try: Number = Record['IS']
		except KeyError: Number = ''
		#
		Organizations = ''
		#
		#JAP added support for BP as begin page
		try:
			endPage = Record['EP']
			try: Pages = '-'.join( (Record['SP'] , endPage) )
			except KeyError: 
			       try: Pages = '-'.join( (Record['BP'] , endPage) )
			       except KeyError: Pages = endPage
		except KeyError:
			try: Pages = Record['SP']
			except KeyError: 
			    try: Pages = Record['BP']
			    except KeyError: Pages = ''
		#
		try: publiAddress = Record['CY']
		except KeyError: publiAddress = ''
		if publiAddress:
			try: Publisher = ', '.join( (Record['PB'], publiAddress) )	# Publisher, Address
			except KeyError: Publisher = publiAddress
		else:
			try: Publisher = Record['PB']
			except KeyError: Publisher = ''
		#
		School = ''
		#
		try: Series = Record['T3']
		except KeyError: Series = ''
		#
		try:
			Title = Record['T1']
		except KeyError:
			try: Title = Record['TI']
			except KeyError:
				if Bibliographic_Type != 'BOOK':
					try:
						Title = Record['BT']
					except KeyError:
						Title = ''
				else:
					Title = ''
		#
		Report_Type = ''
		#
		try: Volume = Record['VL']
		except KeyError: Volume = ''
		#
		try: Year = Record['Y1'].split('/')[0]
		except:
			try: Year = Record['PY'].split('/')[0]
			except: Year = ''
		#
		try: URL = Record['UR']
		except KeyError: URL = ''
		#
		try: Custom1 = Record['U1']
		except KeyError: Custom1 = ''
		#
		try: Custom2 = Record['U2']
		except KeyError: Custom2 = ''
		#
		try: Custom3 = Record['U3']
		except KeyError: Custom3 = ''
		#
		try: Custom4 = Record['U4']
		except KeyError: Custom4 = ''
		#
		try: Custom5 = Record['U5']
		except KeyError: Custom5 = ''
		#
		try: ISBN = Record['SN']
		except KeyError: ISBN = ''
		#
		try: Abstract = Record['N2']
		except KeyError:
			try: Abstract = Record['AB']		# ScienceDirect uses 'AB' for Abstracts instead of 'N2'
			except KeyError: Abstract = ''
		#
		#print [Identifier, Bibliographic_Type,Address, Annote, Author, Booktitle, Chapter, Edition, Editor,HowPublished, Institution, Journal, Month, Note, Number,Organizations, Pages,Publisher,School, Series, Title, Report_Type, Volume,Year,URL,Custom1,Custom2,Custom3,Custom4,Custom5,ISBN,Abstract]
		return [None,Identifier, Bibliographic_Type, Address, Annote, Author, Booktitle, Chapter, Edition, Editor,HowPublished, Institution, Journal, Month, Note, Number,Organizations, Pages, Publisher, School, Series, Title, Report_Type, Volume,Year,URL,Custom1,Custom2,Custom3,Custom4,Custom5,ISBN,Abstract]
