namespace eval ImportExport {


# sets up the window for the import/export
# defaults appropriate global vars if they arent passed as params
# this is for use by the developers API
proc {setup} {{how ""} {tablename ""} {filename ""} {delim ""} {nullas "\\N"} {oids 0}} { 
global PgAcVar CurrentDB
	if {$CurrentDB==""} return;
	set PgAcVar(impexp,how) $how
	set PgAcVar(impexp,tablename) $tablename
	set PgAcVar(impexp,filename) $filename
	set PgAcVar(impexp,delimiter) $delim
	set PgAcVar(impexp,nullas) $nullas
	set PgAcVar(impexp,withoids) $oids
	# well if theres no filename we have to show a window and ask for one
	if {$PgAcVar(impexp,filename)==""} {
		Window show .pgaw:ImportExport
		if {$PgAcVar(activetab)==[intlmsg Tables]} {
			set tn [Mainlib::get_dwlb_Selection]
			set PgAcVar(impexp,tablename) $tn
			if {$tn!=""} {set PgAcVar(impexp,filename) "$tn.txt"}
		}
		.pgaw:ImportExport.expbtn configure -text [intlmsg $how]
	}
}; # end proc setup


# performs the actual import or export
proc {execute} {} {
global PgAcVar CurrentDB
if {$PgAcVar(impexp,tablename)==""} {
	showError [intlmsg "You have to supply a table name!"]
} elseif {$PgAcVar(impexp,filename)==""} {
	showError [intlmsg "You have to supply a external file name!"]
} else {
	# using delimiters ?
	if {$PgAcVar(impexp,delimiter)==""} {
		set delims ""
	} else {
		set delims " USING DELIMITERS '$PgAcVar(impexp,delimiter)'"
	}
	# importing or exporting ?
	if {$PgAcVar(impexp,how)==[intlmsg Import]} {
		set oper "FROM stdin"
		set rw "r"
	} else {
		set oper "TO stdout"
		set rw "w"
	}
	# using oids ?
	if {$PgAcVar(impexp,withoids)} {
		set withoids " WITH OIDS "
	} else {
		set withoids ""
	}
	# set nulls as
	set nullas " WITH NULL AS '$PgAcVar(impexp,nullas)'"

	set sqlcmd "COPY \"$PgAcVar(impexp,tablename)\" $withoids $oper $delims $nullas"
	#tk_messageBox -message $sqlcmd

	if {[catch {::open "$PgAcVar(impexp,filename)" $rw} fid]} {
		showError [intlmsg "Can't open the file $PgAcVar(impexp,filename).  Check file permissions!"]
	} else {
		setCursor CLOCK

		# this row count check should be done elsewhere but for now...
		set sql "SELECT * FROM \"$PgAcVar(impexp,tablename)\""
		set cres [pg_exec $CurrentDB $sql]
		set xfer_tot [pg_result $cres -numTuples]
		pg_result $cres -clear
		set xfer_prog 0

		set pgres [pg_exec $CurrentDB $sqlcmd]
		set pgrestr [pg_result $pgres -status]

		# lets make a progress dialog
		# it will work someday
		# but only display it if we are being run interactively
		#if {[winfo exists .pgaw:ImportExport]} {
		#	set xfer_dlg [ProgressDlg::create .pgaw:ImportExport.xfer_dlg \
		#		-textvariable PgAcVar(impexp,how) \
		#		-variable xfer_prog \
		#		-maximum 100]
		#}
		#tkwait visibility $xfer_dlg

		# importing
		if {$pgrestr=="PGRES_COPY_IN"} {
			set row 1
			set bad_rows 0
			set skip_row 0
			set xfer_tot [file size $PgAcVar(impexp,filename)]
			while {![eof $fid]} {
				set bufcnt [gets $fid buf]
				if {$bufcnt>0} {
					catch {puts $CurrentDB $buf}
				}
				# update the progress bar variable
				set xfer_prog \
					[expr int((double([tell $fid])/double($xfer_tot))*100)]
				set pgrestr [pg_result $pgres -status]
				# another good row, hurray
				if {$pgrestr=="PGRES_COPY_IN"} {
					incr row
					# need to worry about previous bad rows
					if {$row==$skip_row} {
						# stop this transfer, then start again
						catch {puts $CurrentDB "\\."}
						set pgres [pg_exec $CurrentDB $sqlcmd]
						# make sure we skip this bad row
						incr row
					}
				# else deal with the bad row
				} else {
					puts "Bad line #$row: $buf"
					incr bad_rows
					set skip_row $row
					# stop this transfer, then start again
					pg_result $pgres -clear
					#catch {puts $CurrentDB "\\."}
					set pgres [pg_exec $CurrentDB $sqlcmd]
				}
			}
			# file is done
			if {$pgrestr=="PGRES_COPY_IN"} {
				if {[catch {puts $CurrentDB "\\."}]} {
					# the transfer failed to complete
					set pgrestr [pg_result $pgres -status]
					showError [intlmsg "Failed to import!\n$pgrestr"]
				}
			}
		# exporting
		} elseif {$pgrestr=="PGRES_COPY_OUT"} {
			set row 1
			while {$pgrestr=="PGRES_COPY_OUT"} {
				set bufcnt [gets $CurrentDB buf]
				if {$bufcnt>0} {
					catch {puts $fid $buf}
				}
				# update the progress bar variable
				set xfer_prog \
					[expr int((double($row)/double($xfer_tot))*100)]
				set pgrestr [pg_result $pgres -status]
				incr row
			}
		# not sure how we get here but
		} else {
			showError [intlmsg "Another import/export is occurring.  Please wait!\n$pgrestr"]
		}
		# close the progress dialog
		#if {[winfo exists $xfer_dlg]} {
		#	destroy $xfer_dlg
		#}
		set pgrestr [pg_result $pgres -status]
		setCursor DEFAULT
		pg_result $pgres -clear
		::close $fid
		if {$pgrestr=="PGRES_COMMAND_OK"} {
			# only say we are finished if fired from the menu command
			if {[winfo exists .pgaw:ImportExport]} {
				tk_messageBox -title [intlmsg Information] \
					-message [intlmsg "Operation completed!"]
			}
		} else {
			showError [intlmsg "Failed to import/export!\n$pgrestr"]
		}
	}
}
}; # end proc execute


}


### END ImportExport NAMESPACE ###

### BEGIN Visual Tcl code ###

proc vTclWindow.pgaw:ImportExport {base} {
	if {$base == ""} {
		set base .pgaw:ImportExport
	}
	if {[winfo exists $base]} {
		wm deiconify $base; return
	}
	toplevel $base -class Toplevel
	wm focusmodel $base passive
	wm geometry $base 335x180+259+304
	wm maxsize $base 1280 1024
	wm minsize $base 1 1
	wm overrideredirect $base 0
	wm resizable $base 0 0
	wm title $base [intlmsg "Import-Export table"]
	label $base.l1  -borderwidth 0 -text [intlmsg {Table name}]
	entry $base.e1  -background #fefefe -borderwidth 1 \
		-textvariable PgAcVar(impexp,tablename) 
	label $base.l2  -borderwidth 0 -text [intlmsg {File name}]
	entry $base.e2  -background #fefefe -borderwidth 1 \
		-textvariable PgAcVar(impexp,filename) 
	button $base.browsebtn  -borderwidth 1 -text [intlmsg Browse] -command {
		set types {
			{{Text Files}	{.txt}}
			{{All Files}	*}
		}
		if {[.pgaw:ImportExport.expbtn cget -text]=="Import"} {
			set tkget "tk_getOpenFile"
		} else {
			set tkget "tk_getSaveFile"
		}
		if {[catch {$tkget -defaultextension .txt -filetypes $types \
			-title [.pgaw:ImportExport.expbtn cget -text]} \
			PgAcVar(impexp,filename)] || \
			[string match {} $PgAcVar(impexp,filename)]} return
	}	
	label $base.l3  -borderwidth 0 -text [intlmsg {Field delimiter}]
	entry $base.e3  -background #fefefe -borderwidth 1 \
		-textvariable PgAcVar(impexp,delimiter) 
	label $base.lnullas  -borderwidth 0 -text [intlmsg {Nulls As}]
	entry $base.enullas  -background #fefefe -borderwidth 1 \
		-textvariable PgAcVar(impexp,nullas)
	button $base.expbtn  -borderwidth 1 -text [intlmsg Export] \
		-command {
			ImportExport::execute
			Window destroy .pgaw:ImportExport
		}
	button $base.cancelbtn  -borderwidth 1 \
		-command {Window destroy .pgaw:ImportExport} -text [intlmsg Cancel]
	checkbutton $base.oicb  -borderwidth 1  \
		-text [intlmsg {with OIDs}] -variable PgAcVar(impexp,withoids) 
	place $base.l1  -x 15 -y 15 -anchor nw -bordermode ignore 
	place $base.e1  -x 115 -y 10 -height 22 -anchor nw -bordermode ignore 
	place $base.l2  -x 15 -y 45 -anchor nw -bordermode ignore 
	place $base.e2  -x 115 -y 40 -height 22 -anchor nw -bordermode ignore 
	place $base.browsebtn  -x 265 -y 40 -height 25 -width 60 \
		-anchor nw -bordermode ignore 
	place $base.l3  -x 15 -y 75 -height 18 -anchor nw -bordermode ignore 
	place $base.e3  -x 115 -y 74 -width 33 -height 22 \
		-anchor nw -bordermode ignore 
	place $base.lnullas  -x 15 -y 105 -height 18 -anchor nw -bordermode ignore 
	place $base.enullas  -x 115 -y 104 -width 33 -height 22 \
		-anchor nw -bordermode ignore 
	place $base.expbtn  -x 60 -y 140 -height 25 -width 75 \
		-anchor nw -bordermode ignore 
	place $base.cancelbtn  -x 155 -y 140 -height 25 -width 75 \
		-anchor nw -bordermode ignore 
	place $base.oicb  -x 170 -y 105 -anchor nw -bordermode ignore
}


