# DisableEditing
# This procedure disallows editing part of the file tagged by 
# tagname.
#
# Arguments
#	tagname: disables editing for the particular tag.

proc DisableEditing { tagname }  {
	global ownedStart
	.text tag configure $tagname  -background "light pink"
	.text tag bind $tagname <Enter>  { 
		.text	configure -state disabled 
	}
	.text tag bind $tagname <KeyPress>  { 
		.text	configure -state disabled 
	}
	.text tag bind $tagname <ButtonPress>  { 
		.text configure -state disabled 
	}
	.text tag bind $tagname <Leave>  { 
		if { [.text tag nextrange sel 1.0 end] != ""} {
			set Start  [.text index "sel.first linestart"]
			set Finish  [.text index "sel.last lineend"]
			if { [findConflict $Start $Finish] == 1 } {
				.text mark set insert 1.0
			}
		}
		.text	configure -state normal 
	}
	.text tag bind $tagname <KeyPress>  { 
		.text configure -state normal
		if [catch { .text set insert $ownedStart }] {
			.text mark set insert 1.0 
		}
	}
	.text tag bind $tagname <ButtonRelease>  { 
		.text configure -state normal
		if [catch { .text set insert $ownedStart }] {
			.text mark set insert 1.0 
		}
	}
}

bind .text <ButtonRelease-1>	 {
	[list checkPos ] 
}
proc checkPos { } {
	if { [.text compare "insert -1 c" == "insert -1 line lineend"]  } { 
				.text mark set insert  "insert -1 c"
	}
	if { [.text compare "insert -1 c" == "insert -1 line lineend"]  } { 
		.text mark set insert  "insert +1 c"
	}
}
# SelectAreaToOwn
#
#
bind .text <Key> {
	global fileName
	global sock
	global updateComplete
	global offsetFromAdjacent
	global offset
	global adjacentPidVal
	global ownedstart
	global ownedfinish
	global RetVal
#	set RetVal 0
 	switch -exact -- %K	{
		F27 - 
		F35 -
		F33 -
		F29 -
		Left -
		Control_L -
		Shift_L -
		Alt_L -
		Left  {
			# if { [.text tag names "insert - 1 lines" ]!= "free" &&  [.text tag names "insert -1 lines"] !=$pidVal} {
			#	.text mark set insert  "insert +1 lines"
			# }
			if { [.text compare "insert -2 c" == "insert -1 line lineend"]  } { 
				.text mark set insert  "insert -2 c"
				break
			}
			if { [.text compare "insert" == 1.1] } {
				break
			}
		} 
		Up  {
			if { [.text tag names "insert - 1 lines" ]!= "free" &&  [.text tag names "insert -1 lines"] !=$pidVal} {
				# .text mark set insert  "insert +1 lines"
				break
			}
		}
		Down {	
			if { [.text tag names "insert +1 lines +1 c" ] != "free" &&  [.text tag names "insert +1 lines"] !=$pidVal} {
				# .text mark set insert  "insert -1 lines"
				break
			} 
		}
		Shift_R -
		Right -
		Alt_R  {	
			# if { [.text tag names "insert +1 lines +1 c" ] != "free" &&  [.text tag names "insert +1 lines"] !=$pidVal} {
				# .text mark set insert  "insert -1 lines"
			#	break
			# } 
			# if moving into the first column move out
			if { [.text compare "insert +1 c" == "insert +1 line linestart"]  } { 
			#	.text insert "insert + 1 lines linestart"  " "
				if { [.text tag names "insert +2 c" ] != "free" &&  [.text tag names "insert +2 c"] !=$pidVal} {
					break
			 	}  
				.text mark set insert "insert +1 line linestart +2 c"
				break
			}
		}
		Home {
			.text mark set insert "insert linestart + 1 c"
			break
		}
		F1 {	
			if { [.text tag names insert] == "free"} {
				#	puts "Trying to select a free line"
				# need to check if this is really needed
				if { [.text tag nextrange sel 1.0 end] != ""} {
					set Start  [.text index "sel.first linestart"]
					set Finish  [.text index "sel.last lineend"]
					if { [findConflict $Start $Finish] == 1 } {
					#	puts "Do nothing "
					} else {
				 	catch {.text tag remove owned ownedstart} 
					set newContents [getLatestOwned]
					append line_out	serverPushDocument,
					append line_out $fileName
					append line_out ,
					append line_out $newContents
					puts $sock $line_out	
					unset line_out
					if { [info exists ownedstart] } {
						.text tag remove $pidVal $ownedstart $ownedfinish
					# previously owned region no longer
					# of interest
					}
					set present [.text index insert]
					# puts "present"
					# puts $present
					# set ownedStart  [.text index "sel.first linestart"]
					set ownedStart  [.text index "sel.first linestart "]
					# puts "Owned Start"
					# puts $ownedStart
				        set offset [subtractIndices $ownedStart $present]
					# puts "F1:offset is $offset"
					# starting index of newly owned region
					set ownedEnd [.text index "sel.last +1 lines linestart"]
					# puts "OwnedEnd"
					# puts $ownedEnd
					# ending index of newly owned region
					set ownedLines [subtractLines $ownedStart $ownedEnd ]
					# puts "OwnedLInes"
					# puts $ownedLines
					# number of lines owned	
					.text tag remove sel  sel.first sel.last
					findAdjacentPidVal $ownedStart 
					append line_out updateOwnedList,
				#	puts "FileName is "
					# puts $fileName
					append line_out $fileName
					append line_out ,
					append line_out $adjacentPidVal
					append line_out ,
					append line_out $offsetFromAdjacent
					append line_out ,
					append line_out $ownedLines
					puts $sock $line_out	
					unset line_out 
					set updateComplete 0
                                	tkwait variable  updateComplete
                                	# wait for update to be complete
				}
				}
			}	
		}
		default {
			
		#	puts "trying to edit a line"

			if { [string match %K "Return"]} {
#				set RetVal 1
		 		.text insert insert "\n "
				.text insert "insert +1 lines linestart" " "	
			}	
			if { [.text tag names insert] == "free" && [.text tag nextrange sel 1.0 end] == ""} {
			#		puts "Trying to edit a free line"
				# need to check if this is really needed
					# puts "Trying to edit a free line"
					# just owned a new line 
					# This means that previously owned 
					# region needs to be updated and 
					# the new region needs to be notified 
					# to all clients.
					# first send previously owned region
					# to the server
					set newContents [getLatestOwned]
					# puts "Free Line Edit: New Contents"
					# puts $newContents
					# get latest owned  and send to server
					# Editing Free selected Area
					append line_out	serverPushDocument,
					append line_out $fileName
					append line_out ,
					append line_out $newContents
			#		puts $line_out
					puts $sock $line_out	
					unset line_out
					if { [info exists ownedstart] } {
						.text tag remove $pidVal $ownedstart $ownedfinish
					# previously owned region no longer
					# of interest
					}
					set present [.text index insert]
					# puts "Present is "
					# puts $present
					# set ownedStart  [.text index "insert linestart"]
					set ownedStart  [.text index "insert linestart "]
					# puts "Owned Start"
					# puts $ownedStart
				        set offset [subtractIndices $ownedStart $present]
				#	puts "Default:Offset is $offset"
					# find offset from start of owned region of current
					# cursor position and record it.

					# starting index of newly owned region
					set ownedLines 1
					# ending index of newly owned region
					# send request to update server's buffer
					findAdjacentPidVal $ownedStart 
					# puts  "Adjacent Pid Value is"
					# puts  $adjacentPidVal
					# the pid value of adjacent owned region
					append line_out updateOwnedList,
					# puts "FileName is "
					# puts $fileName
					append line_out $fileName
					append line_out ,
					append line_out $adjacentPidVal
					append line_out ,
					append line_out $offsetFromAdjacent
					append line_out ,
					append line_out $ownedLines
			#		puts $line_out
					puts $sock $line_out	
					unset line_out 
					set updateComplete 0
                                	tkwait variable  updateComplete
                                	# wait for update to be complete
				}	
			# CHANGED
			if { [string match %K "Return"]} {
				break
			}
			# CHANGED
			# CHANGED
			if { [string match %K "BackSpace"] && [.text compare "insert -2 c" == "insert -1 line lineend"]  } { 
				.text mark set insert  "insert -2 c"
				break
			}
 			if {  [string match %K "Home"]  && [ .text compare "insert -2 c" == "insert -1 line lineend"]  } { 
				.text mark set insert  "insert -2 c"
				break
			}
			# CHANGED
			if { [string match %K "BackSpace"] && [.text compare "insert -1 c" == "insert -1 line lineend"] && [string compare [.text tag names "insert"] [.text tag names "insert -1 c"]] } { 
# make sure that the backspace is into a free section.. 
					set prevOwned  ""
					set  newOwned ""
					 .text tag remove free "insert linestart" "insert+1 lines linestart"
					 set ownedRange [.text tag ranges $pidVal]
        				if {$ownedRange!=""} {
						set first [lindex $ownedRange 0]
						set last [lindex $ownedRange 1]
						lappend prevOwned $first
						lappend prevOwned $last
						# keep previously owned range to
						# update server
					} else {
						set prevOwned " "
					}
					.text tag remove owned ownedstart 
					.text mark unset ownedstart 
					.text mark set ownedstart "insert  linestart"
					.text tag add $pidVal ownedstart ownedfinish
					set ownedRange [.text tag ranges owned]
					set first [lindex $ownedRange 0]
					set last [lindex $ownedRange 1]
					lappend newOwned $first
					lappend newOwned $last
					.text mark gravity ownedstart left
       					.text mark gravity ownedfinish right

					append line_out updateOwnedList,
					append line_out $fileName
					append line_out ,
					append line_out $prevPidVal
					append line_out ,
					append line_out $ numLines
					puts $sock $line_out	
					unset line_out 
					unset prevOwned 
					unset newOwned 
				}	
		}
	}
}
proc findAdjacentPidVal { ownedStart } {
	global offsetFromAdjacent 
	global adjacentPidVal
	global pidVal

	set offsetFromAdjacent 0
	set count [expr $ownedStart -1]
	# puts "Finding Adjacent: COunt is "
#	puts $count
	 
	while { $count > "0.0" } {
		incr offsetFromAdjacent 
		# Last line of adjacent pid value  is one more line away
		if { [.text tag names $count] != "free"  && [.text tag names $count ] != $pidVal } {
			# puts "Finding Adjacent: Found owned "
			set adjacentPidVal [.text tag names "$count"]
			# puts $adjacentPidVal
			 # puts $count
			return
			# found an adjacent owner 
		}
		set count [expr $count -1]
		# puts "Finding Adjacent: Count is "
		# puts $count
	}
	# puts "Returning TOP"
	set adjacentPidVal "TOP"
	return 
	# did not find any owner
} 

proc findConflict { Start Finish } {
	while { $Finish > $Start } {
		set names [.text tag names $Finish]
	#	puts $names
		if { [lsearch -exact $names "free"] == -1 } {
			return 1
 		}
		set Finish [expr $Finish -1]
	}
	return 0
}
# addIndices 
#
#	Increment tag to new position
#	Add the value of one tag to another by adding the lines to lines
#	and characters to characters 
#
#	Arguments:
#		tag1 : Should be at the linestart
#		tag2 : The two tags to be added together
#
#		newtag: Tag with value tag1 + tag2

# proc incrementtags { tag1 tag2 } {

proc addIndices { tag1 tag2 } {
	regexp {([^\.]+)(.*)} $tag1 useless tag1lines tag1chars
	regexp {([^\.]+)(.*)} $tag2 useless tag2lines tag2chars
	set newtaglines [expr $tag1lines +  $tag2lines]
	append newtag ${newtaglines}$tag2chars 
	return $newtag
}
proc addLines { tag1 tag2 } {
	regexp {([^\.]+)(.*)} $tag1 useless tag1lines tag1chars
	regexp {([^\.]+)(.*)} $tag2 useless tag2lines tag2chars
	set newtaglines [expr $tag1lines +  $tag2lines]
	return $newtaglines
}
proc subtractIndices { tag1 tag2 } {
	regexp {([^\.]+)(.*)} $tag1 useless tag1lines tag1chars
	regexp {([^\.]+)(.*)} $tag2 useless tag2lines tag2chars
	set newtaglines [expr $tag2lines -  $tag1lines]
	append newtag ${newtaglines}$tag2chars 
	return $newtag
}
proc subtractLines { tag1 tag2 } {
	regexp {([^\.]+)(.*)} $tag1 useless tag1lines tag1chars
	regexp {([^\.]+)(.*)} $tag2 useless tag2lines tag2chars
	set newtaglines [expr $tag2lines -  $tag1lines]
	return $newtaglines
}
