## Regression Demo with Data Sheet, check boxes, and slider.
local({
  require(RGtk) || stop("RGtk library not available")
  require(gtkDevice) || stop("gtkDevice library not available")
  require(MASS)
 ## Set up main window
  wRegDemo <- gtkWindow(show=FALSE)
  wRegDemo$AddCallback( "destroy-event", function(x,ev)cat("Closing\n"))  

  wRegDemo$SetTitle("Regression Demo Version 3")

  ## Create box1 to go into the main window
  box1 <- gtkVBox( show =FALSE, spac=10)
    box1$SetBorderWidth(10)
    wRegDemo$Add( box1)
    box1$Show()
   ## Initial Label:
  label1 <-  gtkLabel( "Change numerical values to move points.",
                      show=FALSE)
   label1$SetJustify("left")
   label1$Show()
  box1$PackStart(label1)

  ##within box 1 put several items side-by-side, so create an Hbox to hold them
  box2 <- gtkHBox(show=FALSE,spac=10)
  box2$SetBorderWidth(10)

  ## Create initial Data Table
  x <- sort(rnorm(10, 100,10))
  reg.frame <- data.frame(x=round(x), y = round(x + rnorm(10,0,4)))
  xlimits <- range(reg.frame$x)
  ylimits <- range(reg.frame$y)

  checklm <- gtkCheckButtonNewWithLabel("Show Least Squares Fit (Black)",FALSE)
  checklm$SetUsize(20,20)
  checkrlm <- gtkCheckButtonNewWithLabel("Show Resistant Fit (Red)", FALSE)
  checkrlm$SetUsize(20,20)
  checkrlm$SetActive(FALSE)
  checklm$SetActive(TRUE)
  textrlm <- gtkText();  textrlm$SetUsize(20,20)
  textlm <- gtkText();  textlm$SetUsize(20,20)

  ## Setup Plotting Area
  drawArea <- gtkDrawingArea()
  drawArea$SetUsize(300,300)
  asGtkDevice(drawArea)
  par(mar=c(4,4,2,2)+.01)

  loess.span <- .5
  lmcoef <- lm(y~x, data = reg.frame)$coef
  rlmcoef <- rlm(y~x, data = reg.frame)$coef

  redraw <- function(...){
     ## function to plot points and draw regression line
     plot(y ~ x, data = reg.frame,  xlim=xlimits, ylim=ylimits,
          xlab = "x",ylab="y", pch = 16, col=4)
     if( checklm$GetActive() ) {
       lmcoef <<- lm(y~x, data = reg.frame)$coef
       abline(lmcoef, col=1)}
     if( checkrlm$GetActive() )  {
       rlmcoef <<- rlm(y~x, data = reg.frame)$coef
       abline(rlmcoef, col=2)}
     lines(lowess(reg.frame$x, reg.frame$y, loess.span), col=4)
     if( textrlm$GetLength() >0)
       textrlm$BackwardDelete(nchars=  textrlm$GetLength() )
     textrlm$Insert(char= (t1 =paste("Robust Fit:    y =", round(rlmcoef[1],2),
                          "+", round(rlmcoef[2],2),"x")), length =  nchar(t1) )
     if( textlm$GetLength() >0)
        textlm$BackwardDelete(nchars= textlm$GetLength() )
     textlm$Insert(char= (t2 =paste("Least Squares: y =", round(lmcoef[1],2),
                         "+", round(lmcoef[2],2),"x")), length = nchar(t2) )
  }

  if(require(RGtkExtra)){
    ## Use dataViewer code.  O/wise create editable text windows instead
    sheet <- gtkSheetNew(nrow(reg.frame), 2, title = "Regression Data", 
        show = FALSE)
     sheet$ColumnButtonAddLabel(0, "x")
     sheet$ColumnButtonAddLabel(1, "y")
     sheet$ShowColumnTitles()
     for (j in 1:2) {
       for (i in 1:nrow(reg.frame)) {
            sheet$SetCellText(i - 1, j - 1, as.character(reg.frame[i,j]))
        }
     }
    floor.ceiling <- function(x,floor,ceiling=NULL){
      if(length(floor)==2 & is.null(ceiling)){
        ceiling <- max(floor)
        floor <- min(floor)
      }
      if (x > ceiling) return(ceiling)
      return(max(c(floor,x)))
    }
    sheet$AddCallback("set-cell", function(sheet, i, j) {
      ## Function to replot points and redraw the regression line
      ## If input is off the "page", it moves points
      ##   to the edge of the plotting region.
      newVal <- as.numeric(sheet$CellGetText(i, j))
      if (reg.frame[i + 1, j + 1] != newVal){
        if(j == 0)   ## x column
           sheet$SetCellText(i, j,
                  as.character(newVal <- floor.ceiling(newVal,xlimits)))
        else if(j == 1){
           sheet$SetCellText(i, j,
                  as.character(newVal <- floor.ceiling(newVal,ylimits)))
        }
        reg.frame[i+1,j+1] <<- newVal
        redraw()
      }
    })
    box2$PackStart(sheet)
    sheet$Show()
  }else{
    ##  RGtkExtra not available.
    ##  Does not attempt to handle off-the-page points,
    ##  Changes the plotted region with each change in the data.
    
    ## Setup printable version of x in it's own text widget
    xtxt <- paste(c("x", as.character(reg.frame$x)), collapse="\n")
     textx <- gtkText()
     textx$SetEditable(TRUE)
     textx$SetUsize(70,50)
     xNchar <- nchar(xtxt)
     textx$Insert(chars=xtxt, length= xNchar )
    box2$PackStart(textx)

    ## Add Callback when x is changed
    textx$AddCallback("insert-text",
                      function(...) {    ##need a timer here to slow input?
                   tmp <- gtkEditableGetChars(textx,start=1,
                                              end=textx$GetLength())
                   xNchar <- nchar(xtxt)
                   reg.frame$x <<- as.numeric(unlist(strsplit(tmp,"\n"))[-1])
                   redraw()
                  })

    ## Printable version of y in it's own text widget
    ytxt <- paste(c("y",as.character( reg.frame$y)), collapse="\n")
    texty <- gtkText()
    texty$SetEditable(TRUE)
    yNchar <- nchar(ytxt)
    texty$SetUsize(70,50)
    texty$Insert(chars=ytxt, length= yNchar )
    box2$PackStart(texty)

    ## callback for when y is changed
    texty$AddCallback("insert-text",
                  function(...) {    ##need a timer here to slow input
                     tmp <- gtkEditableGetChars(texty,start=1,
                                                end=texty$GetLength())
                     yNchar <- nchar(ytxt)
                     reg.frame$y <<- as.numeric(unlist(strsplit(tmp,"\n"))[-1])
                     redraw()
                  })
  }
  ## Now draw the plot
  redraw()
  box2$PackStart(drawArea, expa=TRUE,fill= TRUE)
  drawArea$Show()

  box1$PackStart(box2, expa=TRUE,fill= TRUE)
  box2$Show()

  # Table to hold Check Buttons and loess-smoothness slider
  table1 <- gtkTable(3,2, homo=TRUE, show=FALSE)
  table1$Attach(checklm,  left.attach=0, right.attach=1, 
    top.attach=0, bottom.attach=1)
  table1$Attach(checkrlm,  left.attach=0, right.attach=1, 
    top.attach=1, bottom.attach=2)

  ## Add callbacks for the toggled buttons
  checklm$AddCallback("toggled", function(...) redraw(...))
  checklm$Show()
  checkrlm$AddCallback("toggled",function(...) redraw(...))
  checkrlm$Show()

   smoothness <-  gtkAdjustment(loess.span, 0, 1.1, .05, .1, .1)
   hscale <- gtkHScale (smoothness)
   hscale$SetUsize ( 100, 20)
   # Create a callback for when the slider thumb is moved.
   # This allows the span to vary from 0 to 1 with increments of .1
  smoothness$AddCallback("value-changed",
                  function(adj) {  ##need a timer here to slow input
                     tmp <- adj$GetValue()
                     if(tmp == 0)
                       return()
                     loess.span <<- tmp
                     redraw()
                  })
     
   label2 <-  gtkLabel(
       "Smoothness of the Lowess smoother goes from 0 to 1.\n Move the slider to set the smoothness", show=FALSE)
   table1$Attach(label2,  left.attach=1, right.attach=2, 
    top.attach=0, bottom.attach=1)
   label2$Show()          
  table1$Attach(hscale,  left.attach=1, right.attach=2, 
    top.attach=1, bottom.attach=2)
   hscale$Show()

  ## Add in text boxes for output
  if( textrlm$GetLength() <1)
   textrlm$Insert(char= (t1 =paste("Robust Fit:    y =", round(rlmcoef[1],2),"+",
                           round(rlmcoef[2],2),"x")), length =  nchar(t1) )
  if( textlm$GetLength() <1)
   textlm$Insert(char= (t2 =paste("Least Squares: y =", round(lmcoef[1],2),"+",
                          round(lmcoef[2],2),"x")), length = nchar(t2) )
   table1$Attach(textlm,  left.attach=0, right.attach=1, 
            top.attach=2, bottom.attach=3)
   table1$Attach(textrlm,  left.attach=1, right.attach=2, 
            top.attach=2, bottom.attach=3)
   box1$PackStart(table1)
   table1$Show()
  wRegDemo$Show()

#    cat("******************************************************\n",
#        "The source for this demo can be found in the file:\n",
#        file.path(system.file(package = "RGtk"), "examples", "RegressionDemo.R"),
#        "\n******************************************************\n")
    
})