.packageName <- "RArcInfo"
get.namesofcoverages <- function(directory) 
{
	directory<-as.character(directory)
#	.Call("get_names_of_coverages", as.character(dir))

	if(length(dir(path=directory, pattern="info"))==1)
	{
		fil<-file.info(dir(path=directory, full.names=TRUE))

		covnames<-(dir(path=directory))[fil$isdir]
		covnames<-covnames[covnames!="info"]
	}
	covnames
}
get.tablenames <-function(infodir) 
{
	data<-.Call("get_table_names", as.character(infodir), PACKAGE="RArcInfo")

	#A data frame with all the data
	data.frame(TableName=I(data[[1]]), InfoFile=I(data[[2]]), NFields=data[[3]], RecSize=data[[4]], NRecords=data[[5]], External=I(data[[6]]))
}
get.tablefields <- function(infodir, tablename) 
{
	data<-.Call("get_table_fields", as.character(infodir), as.character(tablename), PACKAGE="RArcInfo")

	#A data frame with all the data
	data.frame(FieldName=I(data[[1]]), FieldType=data[[2]])
}

get.arcdata <- function(datadir, coverage, filename="arc.adf") 
{
	data<-.Call("get_arc_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")

	#a table (dataframe) with the first seven fields is built
	df<-data.frame(ArcId=data[[1]], ArcUserId=data[[2]], FromNode=data[[3]], ToNode=data[[4]], LeftPoly=data[[5]], RightPoly=data[[6]], NVertices=data[[7]])

	list(df, data[[8]])
}


get.bnddata <- function(infodir, tablename) 
	.Call("get_bnd_data", as.character(infodir), as.character(tablename), PACKAGE="RArcInfo")

get.paldata <- function(datadir, coverage, filename="pal.adf") 
{
	data<-.Call("get_pal_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")

	#a table (dataframe) with the first six fields is built
	df<-data.frame(PolygonId=data[[1]], MinX=data[[2]], MinY=data[[3]], MaxX=data[[4]], MaxY=data[[5]], NArcs=data[[6]])

	list(df, data[[7]])
}

get.labdata <- function(datadir, coverage, filename="lab.adf") 
{
	data<-.Call("get_lab_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")
	data.frame(LabelUserID=data[[1]], PolygonID=data[[2]], Coord1X=data[[3]], Coord1Y=data[[4]], Coord2X=data[[5]], Coord2Y=data[[6]], Coord3X=data[[7]], Coord3Y=data[[8]])
}

get.cntdata <- function(datadir, coverage, filename="cnt.adf") 
{
	data<-.Call("get_cnt_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")

	df<-data.frame(PolygonID=data[[1]], CoordX=data[[2]], CoordY=data[[3]], NLabels=data[[4]])

	list(df, data[[5]])
}

get.toldata <- function(datadir, coverage, filename="tol.adf") 
{
	data<-.Call("get_tol_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")
	data.frame(Type=data[[1]], Status=data[[2]], Value=data[[3]])
}


get.txtdata <- function(datadir, coverage, filename="txt.adf") 
{
	data<-.Call("get_txt_data", as.character(datadir), as.character(coverage), as.character(filename), PACKAGE="RArcInfo")

	df<-data.frame(TxtID=data[[1]], UserId=data[[2]], Level=data[[3]], NVerticesLine=data[[4]], NVerticesArrow=data[[5]], Text=data[[6]])

	list(df, data[[7]])
}


get.tabledata <- function(infodir, tablename) 
{
	data<-.Call("get_table_data", as.character(infodir), as.character(tablename), PACKAGE="RArcInfo")

	df<-data.frame(I(data[[1]]))
	l<-length(data)

	if(l>=2)
	{
		for (i in 2:l)
			df<-cbind(df,I(data[[i]]))
	}

	fields<-get.tablefields(infodir, tablename)
	names(data)<-fields[[1]]

	data
}

e00toavc <- function(e00file, avcdir)
{
	.Call("e00toavc", as.character(e00file), as.character(avcdir), PACKAGE="RArcInfo")
}

avctoe00 <- function(avcdir, e00file)
{
	.Call("avctoe00", as.character(avcdir), as.character(e00file), PACKAGE="RArcInfo") 
}
get.nb<-function(arc,pal,index=NULL)
{
	if(is.null(index))
		index<-1:length(pal[[1]][[1]])

	lindex<-length(index)
	
	nb<-vector(mode="list", length=lindex)

	arcid<-arc[[1]]$ArcId
	lpoly<-arc[[1]]$LeftPoly
	rpoly<-arc[[1]]$RightPoly

	for(p in 1:lindex)
	{
		arcs<-sort(unique(abs(pal[[2]][[ index[p] ]][[1]])))

		if(arcs[1]==0)
			arcs<-arcs[-1]

		arcindex<-as.vector(tapply( arcs , 1:length(arcs),
			function(X,arcid){which(arcid==X)}
			,arcid) )

		thisnb<-c(lpoly[arcindex], rpoly[arcindex])
		nb[[p]]<-sort(unique(thisnb))
	}

	nb
}
#Plots all the arcs imported from an ARC file by get.arcdata

#New: T for new plots
plotarc<-function(arc, new=TRUE, index=NULL, ...)
{
	if(is.null(index))
		index<-1:length(arc[[2]])

	ll<-length(index)

	#We only need the list of arcs, not the dataframe with the other data
	arc<-arc[[2]][index]

	if(new==TRUE)
	{
		if(!exists("xlim") || !exists("ylim") )
		{
			#Calculate the boundary

			x<-arc[[1]][[1]]
			y<-arc[[1]][[2]]
			l<-as.integer(length(x))

			xmin<-min(x)
			xmax<-max(x)
			ymin<-min(y)
			ymax<-max(y)

			nxmin<-min(x)
			nxmax<-max(x)
			nymin<-min(y)
			nymax<-max(y)


			for(i in 2:ll)
			{
				x<-arc[[i]][[1]]
				y<-arc[[i]][[2]]
				l<-as.integer(length(x))

				nxmin<-min(x)
				nxmax<-max(x)
				nymin<-min(y)
				nymax<-max(y)

				if(nxmin<xmin) xmin<-nxmin
				if(nymin<ymin) ymin<-nymin
				if(nxmax>xmax) xmax<-nxmax
				if(nymax>ymax) ymax<-nymax
			}
		}
		else #if(!exists("xlim") || !exists("ylim") )
		{
			xmin<-xlim[1]
			xmax<-xlim[2]
			ymin<-ylim[1]
			ymax<-ylim[2]
		}

		range<-max( c(xmax-xmin, ymax-ymin) )/2

		xmean<-(xmin+xmax)/2
		ymean<-(ymin+ymax)/2


		#Set aspect ratio and display plotting window

		par.in <- par(no.readonly = TRUE)
#		on.exit(par(par.in))

		plot.dim<-c(xmax-xmin, ymax-ymin)
		print(min(par.in$pin)
		                * par.in$fin / max(par.in$fin)
				                * (plot.dim) / max(plot.dim))
		par(pin = min(par.in$pin) 
		* par.in$fin / max(par.in$fin)
		* (plot.dim) / max(plot.dim))

		plot(arc[[1]][[1]], arc[[1]][[2]], xlim=c(xmean-range,xmean+range), ylim=c(ymean-range, ymean+range), type="n", ...)

	}##if(new)

	for (i in 1:ll)
	{
		lines(arc[[i]][[1]], arc[[i]][[2]], ...)
	}

}
#Plots the polygons in pal imported by get.paldata according
#to the arcs in arc (value returned by get.arcdata)
plotpal<-function(arc,pal, new=TRUE, index=NULL,...)
{

	if(is.null(index))
		index<-1:length(pal[[2]])
	#We only need the lists of arcs
	arc<-arc[[2]]
	pal<-pal[[2]]

	larc<-length(arc)
	arcs<-vector(mode="logical", length=larc)


	for(p in index)
	{
		l<-length(pal[[p]][[1]])
		for(a in 1:l)
		{
			arcs[abs(pal[[p]][[1]][a])]<-TRUE	
		}
	}

	plotarc(list(c(0),arc[arcs]), new=new, ...)

}
plotpoly <-function(arc,bnd,pal,index=NULL,col, xratio=1, yratio=1, ...)
{
	if(is.null(index))
	{
		index<-1:length(pal[[1]][[1]])
	}

	lindex<-length(index)
	col<-rep(col,length.out=lindex)	

#Set aspect ratio and display plotting window

	par.in <- par(no.readonly = TRUE)
#	on.exit(par(par.in))

	plot.dim<-c(bnd[3]-bnd[1], bnd[4]-bnd[2])

	rdib<-min(par.in$pin[1]/plot.dim[1],par.in$pin[2]/plot.dim[2])
	plotreg<-c(bnd[[1]],bnd[[1]]+plot.dim[[1]]*rdib,
			bnd[[2]],bnd[[2]]+plot.dim[[2]]*rdib)
	par(pin=c(xratio,yratio)*plot.dim*rdib, usr=plotreg)

	plot((bnd[1]+bnd[3])/2,(bnd[2]+bnd[4])/2,xlim=c(bnd[1],bnd[3]),
			ylim=c(bnd[2],bnd[4]),type="n", ...)	


#First, we just select the arcs we will need. This will speed up
#this function
	palindex<-match(index, pal[[1]]$PolygonId)
	arcindex<-as.vector(sapply(pal[[2]][palindex],function(X){X[[1]]}))
	arcindex<-sort(unique(abs(unlist(arcindex))))[-1]
	
	arc1<-list(arc[[1]][1:7][arcindex,],arc[[2]][arcindex])
	pal1<-list(pal[[1]][1:6][palindex,],pal[[2]][palindex])


	for(i in 1:lindex)
	{


#Now, we plot the polygons

		#This gives us the list of arcs 
		p<-match(index[i], pal1[[1]]$PolygonId)
		p<-pal1[[2]][[p]][[1]]


		#And here we get the "rows" of them in the variable arc
		absp<-abs(p)
		a<-match(absp, arc1[[1]]$ArcId)

		#When p[[j]]==0 it means that the previous arcs build a closed polygon
		#and it can be plotted

		#Default values for x and y coordinates.
		x<-c()
		y<-c()
	
		
		for( j in 1:length(p) )
		{	
	
			if(p[[j]]>0)
                	{
        	                x<-c(x, arc1[[2]][[ a[j] ]][[1]])
       	        	        y<-c(y, arc1[[2]][[ a[j] ]][[2]])
        	        }
       	        	else if(p[[j]]<0)
                	{
				x<-c(x, rev(arc1[[2]][[ a[j] ]][[1]]))
				y<-c(y, rev(arc1[[2]][[ a[j] ]][[2]]))
       	        	}
			else
			{
				if(length(x)>0 && length(y)>0)
				{
					if( (x[1]!=x[length(x)]) || (y[1]!=y[length(y)]) )
					{
						print("The polygon isn't closed")
						x<-c(x,x[1])
						y<-c(y,y[1])
					
						polygon(x,y,col=col[match(index[i], index)])
					}
					else
					{
						polygon(x,y,col=col[match(index[i], index)])
					}

					x<-c()
					y<-c()
				}
			}
		}


		if(length(x)>0 && length(y)>0)
		{
			if(x[1]!=x[length(x)] || y[1]!=y[length(y)] )
			{
				print("The polygon isn't closed")
				print(c(j,p[[j]]))
				x<-c(x,x[1])
				y<-c(y,y[1])
			}
			polygon(x,y,col=col[match(index[i], index)])
		}
	}
}
read.coverage<-function(datadir, coverage)
{
	infodir<-paste(c(datadir,"info/"), collapse="")
	covdir<-paste(c(datadir, coverage), collapse="")

	cov.arc<-get.arcdata(datadir, coverage)
	cov.cnt<-get.cntdata(datadir, coverage)
	cov.bnd<-get.bnddata(infodir, paste( c(casefold(coverage, upper=TRUE), ".BND"), collapse="") )
	cov.lab<-get.labdata(datadir, coverage)

	palfiles<-dir(covdir, pattern="pal.adf")
	palfiles<-c(palfiles, dir(covdir, pattern="*.pal") )

	if( length(palfiles)==1 )
		cov.pal<-get.paldata(datadir, coverage, palfiles[1])
	else
		cov.pal<-NULL

	
	if( length(dir(covdir, pattern="tol.adf"))>0 )
		cov.tol<-get.toldata(datadir, coverage)
	else
	{
		cov.tol<-get.toldata(datadir, coverage, "par.adf")
	}
	
	tblnames<-get.tablenames(infodir)
	
	pattern<-paste( c(casefold(coverage, upper=TRUE), ".*"), collapse="")

	cov.tables<-tblnames[grep(pattern, tblnames[[1]]),]

	cov<-list(datadir=datadir, coverage=coverage, arc=cov.arc, bnd=cov.bnd, cnt=cov.cnt,  lab=cov.lab, pal=cov.pal, palfiles=palfiles, tblnames=cov.tables, tol=cov.tol)

	return(cov)
}
thinl<-function(coord, tol)
{
	tol2<-tol*tol

	x<-coord[[1]]
	y<-coord[[2]]

	npoints<-length(x)
	index<-c(1)
	j<-1
	
	for(i in 2:(npoints-1))
	{
		xx<-x[j]-x[i]
		yy<-y[j]-y[i]
		if((xx*xx+yy*yy)>tol2)
		{
			j<-i
			index<-c(index,i)
		}

	}

	index<-c(index,npoints) #Suggested by Erich Neuwirth	

	list(x[index], y[index])
}

thinlines<-function(arc, tol)
{
	newarc<-list()

	narcs<-length(arc[[1]][[1]])

	newarc<-lapply(arc[[2]],thinl, tol=tol)

	newtable<-arc[[1]]

	newtable$NVertices<-as.numeric( lapply(newarc, function(X){length(X[[1]])})  )
	
	list(newtable, newarc)
}
.First.lib <- function(lib, pkg) {
	library.dynam("RArcInfo", pkg, lib)
}
