#
# QCad
# (c) Q Solutions 1998
#
#
#
#
# 
proc pcbEdit { file {type ""}} {

	set name Pcb_$file
	set win .spe_$name
	upvar #0 $name pcb
	global $name 

	if { ! [winfo exists $win] || ! [info exists pcb(Init)] } {
		catch {unset pcb}
		catch {destroy $win}
		canvasMakeWin $name Pcb $win
		set pcb(File) $file
		sheetDraw $name $pcb(edit,Sheet)
		fileLoad $name $file
		set top [winfo toplevel $win]
		update
		scan [winfo geometry $top] {%dx%d+%d,%d} ww wh wl wr 
		wm minsize $top $ww $wh 
		set pcb(Init) 1
	} else {
		wm deiconify [winfo toplevel $pcb(Win)]
		raise  [winfo toplevel $pcb(Win)]
		focus $pcb(Canvas)
		return
	}
}

###
### CRAP
###  NEED BETTER THAN THIS, create pseudo data array and use normal routines
###
proc pcbReadSch { name } {
	upvar #0 $name schema

	foreach ty $data(TypeList) {
		set id [$canvas create oval -1 -1 1 1 -fill {} -outline {} -tags "$ty System Fixed"]
		$canvas raise $id 
	}
	set item [dbBrowseExist Sch]
	if { $item == "" } { return }
	set itemdata [dbGet Sch $item]
	canvasClear $data(Canvas)
	procZoom $name None
	set canvas $data(Win).rc
	catch {canvas create $canvas}
	set nid [canvasAddList $name 0 [lindex $itemdata 1]]
	set head [lindex $itemdata 0]
	set adata [lindex $head 4]
	array set data $adata 
}

proc pcbXRef {id list} {

	set f [lsearch $list "$id *"]
	if { $f != -1 } {
		set f [lindex $list $f]
		scan $f "%d %d" x f
	}
	return $f
}

proc pcbReadNet { name {item ""}} {
	upvar #0 $name data
	global GBL

	if { $item == "" } {
		set item [dbBrowseExist Net]
	}
	if { $item == "" } { return }
	set file [file join $GBL(vSelTopDir) $GBL(vSelSubDir) $item.net] 
	set f [open $file r] 
	while { ! [eof $f] } {
		array set data [gets $f]
	}
	close $f
	procZoom $name None
	set IDXRef {}
	foreach item  $data(PartList) {
		foreach {ref id partno} $item {}
		catch {unset part}
		Log "Process $ref.$id $partno"
		set partdata [dbGetPart $partno]
		array set part $partdata
		set decal [lindex $part(Part,Decals) 0]
		if { $decal == "" } {
			set Log "$ref part $partno has no decals"
			LogShow
		}
		set nid [newID]
		schLoadDecal $name $nid $decal Decal $ref $partno {} {} 0 0 0
		#set nid [partAddItem $name $decal]
		Log "New id :$nid"
		#partRenumber $name $nid $ref "" {}
		lappend IDXRef [list $id [idNum $nid]]

		Log "$ref $partno $id -> $nid"
	}
	Log "IDXRef: $IDXRef"
	set data(edit,Layer) Silk
	foreach item  $data(NetList) {
		foreach {netname nl} $item {}
		set st [lindex $nl 0]
		scan $st "%d:%d" id0 pin0
		foreach pt [lrange $nl 1 end] {
			scan $pt "%d:%d" id1 pin1
			set ref0 [pcbXRef $id0 $IDXRef]
			set ref1 [pcbXRef $id1 $IDXRef]
			Log "Net $ref0:$pin0 -> Net $ref1:$pin1"
			canvasCreate $name line {0 0 0 0} Net "" "CRef0($ref0) Tie0($ref0:Anchor:$pin0) CRef1($ref1) Tie1($ref1:Anchor:$pin1) Width(13) NoDelete" "-capstyle round"
			set id0 $id1
			set pin0 $pin1
		}
	}
	set data(edit,Layer) Bottom
	procZoom $name Fit
	return ""
}

proc pcbRoute {name {mode ""}} {
	upvar #0 $name data

	if { $mode == "" } { set mode $data(Mode) }
	set tag [tagFind $data(Canvas) $data(cx) $data(cy) 0 0 "Type(Net) Type(Track)" 1]
	if { $tag == ""} { 
		set data(Message) "Not on Net or Track"
		bell 
		return ""
	}
	set lay $data(edit,Layer)

	set type [tagGet $data(Canvas) $tag Type]
	set id [tagTag $data(Canvas) $tag ID]

	### Find Point/Segment
	set coords [$data(Canvas) coords $tag]
	set len [lineSegMax $coords]
	set seg [lineFindSeg $data(cx) $data(cy) $coords]
	set pt [lineFindPoint $data(cx) $data(cy) $coords]
	Log "SelCon @$data(rx),$data(ry) $tag:$id seg $seg pt $pt nseg $len npt [linePointMax $coords]"
	if { $pt != 0 && $pt !=  [linePointMax $coords] } { set pt -1 }
	if { $seg == 0 || $seg == $len } { set seg -1}
	if { $seg != -1 } { set pt -1}
	if { $seg == -1 && $pt == -1 } { 
		procDropAll $name
		set data(Message) "Not End point or segment"
		bell
		return ""
	}
	set end 0
	if { $pt > 0 } { set end 1}
	if { $type == "Track" } {
		set ntag $tag
		set lay [tagGet $data(Canvas) $tag Layer]
	}
	if { $type == "Net" } {
		set ref [tagGet $data(Canvas) $id Tie$end]
		set refpin 0
		scan $ref {%d:%[^:]:%d} refid refty refpin
		Log "id $id Ref $ref :"
		if { $refty != "Track" } {
			set anctag [tagSearchAll $data(Canvas) "withtag Anchor($refid:$refpin)"]
			scan [geomCenter $data(Grid,Step) [$data(Canvas) coords $anctag]] "%f %f" cx cy
			set tend [expr 1 - $end]
			set coords "$cx $cy $data(rx) $data(ry)" 
			set tw [tagGet $data(Canvas) $id Width]
			if {$tw == "" } {set tw 13}
			set data(edit,Layer) $lay
			set ntag [canvasCreate $name line $coords Track "" "Width($tw)" "-width $tw"]
			set tid [tagTag $data(Canvas) $ntag ID]
			set tnum [idNum $tid]
			## Tie net end to track
			tagPut $data(Canvas) $id Tie$end $tnum:Track:1
			tagPut $data(Canvas) $id CRef$end $tnum
			## Make new Net for other end of track
			set data(edit,Layer) Silk
			set etag [canvasCreate $name line [list $cx $cy $cx $cy] Net "" "CRef0($refid) Tie0($refid:Anchor:$refpin) CRef1($tnum) Tie1($tnum:Track:0)"]
			## Set obj to new track object
			## change type to Track to allow extension
			set id $tid
			set end 1
			set pt 1
			set type Track
			set seg -1
		} else {
			set id ID($refid)
			set ntag [tagSearchID $data(Canvas) $id Type(Track)]
			set end  $refpin
			set seg -1
			set pt $refpin
			set type Track
			if { $refpin != 0 } { set pt [linePointMax [$data(Canvas) coords $tag]] }
			Log "Move old $tag $id.$pt.$end" 
		}
	}
	set mfunc "Adjust"
	if { $seg != -1 } { set mfunc "AdjustS" }

	set data(edit,objseg) $seg
	set data(edit,objpoint) $pt
	set data(edit,end) $end

	set data(x) $data(rx)
	set data(y) $data(ry)
	set data(startx) $data(rx)
	set data(starty) $data(ry)

	set data(edit,objItem) [$data(Canvas) type $ntag]
	set data(edit,objTag) $ntag
	set data(edit,objID) $id
	set data(edit,objType) $type
	set data(edit,Layer) $lay

	return $mfunc

}

# binding ensures we have grabbed a track
# split the track into two and grab new track
#
proc procTrackVia {name } {

	upvar #0 $name data

	set tend $data(edit,end)
	set tobj $data(edit,objTag)
	set tid  [tagGet $data(Canvas) $tobj ID]
	set tlay  [tagGet $data(Canvas) $tobj Layer]
	set tw	[tagGet $data(Canvas) $tobj Width]
	if { $tw == {} } {set tw 25}
	set vw [expr $tw * 0.9 / 2]
	#puts "Line $tid: end $tend @[linePointEnd $tend [$data(Canvas) coords $tobj]]"

	set nend 0
	set ref [tagGet $data(Canvas) $tobj CRef$tend]
	if { $ref != "" } {
		set data(Message) "Track end already attached to something"
		bell
		return ""
	}
	set nend 0
	set netobj [tagSearchAll $data(Canvas) "withtag Tie$nend\($tid:Track:$tend)" Type(Net)]
	if {$netobj == "" } {
		set nend 1
		set netobj [tagSearchAll $data(Canvas) "withtag Tie$nend\($tid:Track:$tend)" Type(Net)]
	}
	if {$netobj == "" } {
		set data(Message) "Can't find attached net for track $tid"
		bell
		return
	}
	switch $tlay {
		All		{set tlay Silk}
		Top 	{set tlay Bottom}
		Bottom 	{set tlay Top}
		default {set tlay Bottom}
	}
	set data(edit,Layer) $tlay
	set coords [list $data(rx) $data(ry) $data(rx) $data(ry)]

	# Create New Track
	set ntag [canvasCreate $name line $coords Track "" "Width($tw)" "-width $tw"]
	set ntid  [tagGet $data(Canvas) $ntag ID]
	
	# Attach net end to new track end 1
	tagPut $data(Canvas) $netobj Tie$nend $ntid:Track:1
	tagPut $data(Canvas) $netobj CRef$nend $ntid

	# Create Via
	#
	set data(edit,Layer) All
	set vtag [canvasCreate $name oval [geomSquare $vw $data(rx) $data(ry)] Via "" "Filled Fixed Net(Via)" ""]
	set vid  [tagGet $data(Canvas) $vtag ID]

	# Attach via to old track,  make anchor to tie track to via
	tagPut $data(Canvas) $vtag Anchor $vid:0
	tagPut $data(Canvas) $vtag  Tie$tend $tid:Track:$tend
	tagPut $data(Canvas) $vtag  CRef$tend $tid

	# Attach new track end 0 to via
	tagPut $data(Canvas) $ntag Tie0 $vid:Anchor:0
	tagPut $data(Canvas) $ntag CRef0 $vid

	# Add net to tie new track to old track
	set data(edit,Layer) Silk
	set etag [canvasCreate $name line $coords Net "" "CRef0($ntid) Tie0($ntid:Track:0) CRef1($tid) Tie1($tid:Track:$tend)"]

	# Switch grab to new track and route that
	set data(edit,end) 1
	set data(edit,objseg) -1
	set data(edit,objpoint) 1
	set data(x) $data(rx)
	set data(y) $data(ry)
	set data(startx) $data(rx)
	set data(starty) $data(ry)

	set data(edit,objTag) $ntag
	set data(edit,objID) [tagTag $data(Canvas) $ntag ID]

	set data(edit,Layer) $tlay

	return "" ;# stay in current mode with new track
}






