---------------------------------------------


--- the geberal interface for analysis
--[G.RadioButton]
analysisBoxForAFrame ::  Bool -> [G.RadioButton] ->
     G.Entry  -> [G.VBox] ->   IO G.VBox
analysisBoxForAFrame tf rbutts fe boxes = do
    aBox <- G.vBoxNew False 5
    selectBox <- getSelectBox tf rbutts fe -- this comes from another function
    detailsFrame <- G.frameNew
    G.set detailsFrame [G.frameLabel G.:= " Condition parameters" ]
    table <- tableWithWidgetList False boxes False 2
    --table <- hPanedArea (boxes !! 0) (boxes !! 1) 100
    G.containerAdd detailsFrame selectBox
    G.boxPackStart aBox detailsFrame G.PackNatural 5
    G.boxPackStart aBox table G.PackGrow 2 -- detailsFrame
    return aBox
    --
    where
        getSelectBox :: Bool -> [G.RadioButton] -> G.Entry  -> IO G.HBox
        getSelectBox sE rbutts fileEntry = do
            [thbox,entryBox, tablesBox] <- sequence $ replicate 3 (G.hBoxNew False 2)
            browseButton <- G.buttonNewWithLabel " Load data file "
            --- pack the entry box
            G.boxPackEnd entryBox fileEntry G.PackGrow 4
            G.boxPackStart entryBox browseButton G.PackNatural 2
            G.on browseButton G.buttonActivated $ do
                fileBrowser (Just fileEntry) >>= G.dialogRun  >>= \_ -> return () -- ) >> return ()
            --- put the condition chooser in a box
            let n = length rbutts
            let (condTypes, scnSem) = splitAt (n-2) rbutts
            condBox <- tableWithWidgetList False condTypes False 3
            vButtonTable <- tableWithWidgetList True scnSem True 3
            G.vSeparatorNew >>= \sep -> do
                sep1 <- G.vSeparatorNew
                G.boxPackStart tablesBox  sep1 G.PackNatural 0
                G.boxPackStart tablesBox  vButtonTable G.PackNatural 8
                G.boxPackStart tablesBox  sep G.PackNatural 0
                G.boxPackStart tablesBox  condBox G.PackGrow 5
                --
                --G.containerAdd tablesFrame tablesBox
                if sE then do
                    G.boxPackStart thbox  entryBox G.PackGrow 2
                    G.boxPackStart thbox  tablesBox G.PackGrow 0
                else do
                    G.boxPackStart thbox  tablesBox G.PackGrow 2
                    G.boxPackStart thbox  entryBox G.PackGrow 0
            --
            --detailsFrame <- G.frameNew
            return thbox
   --}
{-
--------------------------------------------------------------------------------------------------
--    Dialog to initialize the network level analyis and related dialiogos and datatypes
--------------------------------------------------------------------------------------------------
--- the maybe here should be a pair of tracking panes
globalAnalysisTop :: Maybe G.Window ->
    Maybe (IORef [Road]) ->
    IO (G.VBox, Maybe AWin,[G.RadioButton], G.Entry , PreviewParms)
globalAnalysisTop  mwin strAndChn = do
    [mainVBox,listsVBox] <- sequence $ replicate 2 (G.vBoxNew False 1)
    [bottomHBox,topHBox, -- condsVBox, topHBox,bottomOBox,
        buttsVBox] <- sequence $ replicate 3 (G.hBoxNew False 1)
    comboList <- sequence $ replicate 5 G.comboBoxNewText
    vsep   <- G.vSeparatorNew
    [hsep, hsep1, hsep2]   <- sequence $ replicate 3 G.hSeparatorNew
    [yearsEntry, distEntry, fileEntry] <- sequence $ replicate 3 G.entryNew
    -- fileEntry is the entry for the file Path. set the size of the entry
    G.widgetSetSizeRequest fileEntry 360 (-1)
    -------------------------------------------------------------------
    prevAnalFrame <- G.frameNew
    -- condTypes
    ------------------------------------------------------------------------------------
    -- the display window
    -- the progress and display buffers
    (scrwin,progressBuffer) <- makeScrolledEntryArea BScroll False True
    G.widgetSetSizeRequest scrwin 60 (-1)
    -------- and updating chains will be added here
    (selectedCondsTable, dispBuffer) <- getSelectedConditionsTable
    ---
    let logProgress   = updateBufferAtEnd progressBuffer
    let add2SeletList = updateBufferAtEnd dispBuffer
    ----- check for extracted conditons
    checkIfExtracted False True logProgress
    -------------------------------------------------------------------
    G.set prevAnalFrame [G.frameLabel G.:= " Condition attribures" ]
    G.containerAdd prevAnalFrame listsVBox -- listsVBox
    G.boxPackStart topHBox prevAnalFrame G.PackGrow 6
    -------------------------------------------------------------------
    mapM_ (\ent -> do
                G.entrySetWidthChars ent 6
                G.entrySetMaxLength ent 6) [yearsEntry, distEntry]
    let [detailsCombo,rNameCombo,rClassCombo,rCodeCombo,srCodeCombo] = comboList
    -- fillToMaxLegth :: [String] -> [String]mapM (G.labelNew . Just)
    let comboNames = ["Road Class: ", "Road Name: ", "SCANNER Section Code: "," SCRIM Section Code: "]
    --mapM_ (\w -> G.miscSetAlignment w 1 0.5) comboNames
    let schms = zip (fillToMaxLegth comboNames)  [rClassCombo,rNameCombo,rCodeCombo,srCodeCombo]
    --let labelAndWidget m a b = labelLeftofWidget a b m
    comboBoxesWithLables <- mapM (\(l,w) -> labelLeftofWidget l w False ) (take 2 schms)
    comboBoxesWithLables1 <- mapM (\(l,w) -> labelLeftofWidget l w False ) (drop 2 schms)
    -- create table
    row1 <- tableWithWidgetList False comboBoxesWithLables False 2
    row2 <- tableWithWidgetList False comboBoxesWithLables1 False 2
    --schmAndClass <- tableWithWidgetList True [row1,row2] True 2
    ------------------------------------ }
    comboRef <- newIORef [] --- the a record to toggle the condition details
    --roadConditionRef
    --- selected,
    detailsListRef <- newIORef ([],[],[])
    advancedRef <- newIORef ([],Nothing)
    dataTypeRef <- newIORef SCANNER -- toggles the curreltly selected data type
    countRef <- newIORef 1 -- a counter ref track what is happings
    rNameRef <- newIORef []
    extractAnal <- newIORef Nothing --- flag to toggle extraction or analysys
    ------------------------------------
    let comboLabels = [" Condition Detail: "]
    let comboLabelPairs = zip comboLabels comboList
    vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    ---
    [rcl,rsc] <-  mapM G.radioButtonNewWithLabel ["Road Class","Section Code"]
    G.radioButtonSetGroup rcl rsc
    --mapM_ (\b -> G.boxPackEnd (vBoxesWithLabels !! 0) b G.PackNatural 6) [rcl,rsc]
    -------------------------------------------------------------------------------
    ---- fork the population of the roads, etc
    ---  We will need to put each road class in a separate file. This wouuld be done when
    ---  When the details of the roas is added
    -- desensetise the combos :
    mapM_ (flip G.widgetSetSensitive False) (map snd schms)
    rtypes <- getRoadClasses >>= return . filter (isAlpha . snd)
    let roadTypes =  map snd $ nubBy (\a b -> snd a == snd b) rtypes
    ----- extract the road classes
    let getClasses = mapM_ (G.comboBoxAppendText rClassCombo) $ map ( :"-roads") roadTypes
    --let getNames   = mapM_ (G.comboBoxAppendText rNameRef) $ map L.unpack rNames
    --forkIO $ mapM_ (G.comboBoxAppendText rCodeCombo) $ map (\(a,_,_) -> L.unpack a) secAndTypes
    -- clearAdd cRef combo list
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    rCodesComboRef <- newIORef [] --- the a record to toggle the condition details
    roadClassAdded <- newIORef False
    {--- fix this
    let getCodesFromClass = do
        index <- G.comboBoxGetActive rClassCombo
        if index >= 0 then  do
            let !codes = [bs | (bs,c) <- rtypes, c == (roadTypes !! index)]
            clearAdd rCodesComboRef rCodeCombo  $ map L.unpack codes --
        else  return ()
    --}
    G.on rClassCombo G.changed $ do
          rclsAdded <- readIORef roadClassAdded
          index <- G.comboBoxGetActive rClassCombo
          if rclsAdded then do
              let des = "Extracting classes for "++[roadTypes !! index]++"-roads"
              logProgress (des ++ " ... ")
              -- forkProcess (Just des) logProgress getCodesFromClass Nothing
          else  do
              let rtyp = roadTypes !! index
              let mkRN1 (a,b,c) = L.unpack c
              let mkSC1 (a,b,c) = L.unpack b
              logProgress ([rtyp] ++"-roads selected")
              rname <- getRoadNamesAndSections (map fst $ filter ((== rtyp) . snd) rtypes) -- >>= return $ map mkSt1
              clearAdd rNameRef rNameCombo (map mkRN1 rname)
              clearAdd rCodesComboRef rCodeCombo (map mkSC1 rname)
              G.widgetSetSensitive rNameCombo True
    --sensetize the combos once the road classes have been extracted
    forkProcess Nothing logProgress getClasses
                        (Just $ mapM_ (flip G.widgetSetSensitive True) [rClassCombo,rCodeCombo])

    --forkProcess Nothing (updateBufferAtEnd progressBuffer) getNames
    --                    (Just $ mapM_ (flip G.widgetSetSensitive True) [rNameCombo,rCodeCombo])
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    -- clearAdd comboRef detailsCombo (map display lst)
    --- update the road class names,codes and section codes upon a election of a road class
    -------------------------------------------------------------------------
    [addButton,analButton,previewButt,clrButt] <- mapM G.buttonNewWithLabel
                                                                [" Add condition details ",
                                                                 " Analyse ", " Extract ",
                                                                 " Edit List "]
    --advOptions <- advancedOptionsWin -- (Just advancedRef)
    -- file entry box vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    let entryLabels = ["  Average maintenance frequency in years: ",
                       "  Average treatment length in kilometers: "]
    let entryPairs = zip entryLabels [yearsEntry, distEntry]
    entryTable <- mapM (\(l,w) -> labelLeftofWidget l w True) entryPairs >>= \eb ->
                        tableWithWidgetList False eb False 10
                   --     [yearsEntry, distEntry]
    -- use the dummy do that none will be set on start up
    dummy  <-  G.radioButtonNew -- WithLabel "
    [nl, sl]  <- mapM G.radioButtonNewWithLabel [" Network Level Analysis "," Scheme/road Level Analysis "]
    G.radioButtonSetGroup dummy nl
    G.radioButtonSetGroup nl sl
    ---
    ---
    --- negative slopes
    negativeSlopes  <- G.checkButtonNew -- WithLabel "
    optsBox <- labelLeftofWidgetE' "Include negative slopes " 1 negativeSlopes True
    --
    mapM_ (\w -> G.boxPackStart optsBox w G.PackGrow 2) [nl,sl]
    --G.boxPackEnd optsBox negativeSlopes' G.PackGrow 2
    -------------------------------------------------------------------------------------
    G.on addButton G.buttonActivated $ do
        -- need here: read inout parameter file
        [str1,str2] <- mapM G.entryGetText [yearsEntry, distEntry]
        negSlope <- G.toggleButtonGetActive negativeSlopes
        -- return () -- temporary
        --
        case (validateEntries [str1,str2] ["years","distance"]) of
            Left [e1,e2] -> do
                index <- G.comboBoxGetActive detailsCombo -- >>= \index ->
                if index >= 0 then do
                    (selected,_,dlist) <- readIORef detailsListRef -- >>=  \ ->  do
                    let sel = (dlist !! index)
                    let str = (display sel) -- ++ (" yrs: "++str1 ++ " dist: "++str2)
                    let message = "You have already added \'" ++ display sel  ++ "\' to\
                                  \ the list of selected conditions."
                    --
                    if sel `elem` selected then
                        runMsgDialog Nothing message Info
                    else do
                        let pm = (fromIntegral e1, fromIntegral e2,negSlope)
                        add2SeletList str
                        modifyIORef detailsListRef (\(a,ps,b) -> (sel : a,pm:ps,b))
                        -- clear the entries and neg slope
                        mapM_ (\ent -> G.entrySetText ent "") [yearsEntry, distEntry]
                        G.toggleButtonSetActive negativeSlopes False
                else
                    runMsgDialog Nothing "Negative index at condition details combo box" Error
            Right string -> runMsgDialog Nothing string Error
    ------------------------------------------------------------------------------------ }
    ---- the scanner or scrim radio butttons
    [d1,d2] <- mapM (\st -> G.radioButtonNewWithLabel st) ["", ""]
    condTypes <- mapM (G.radioButtonNewWithLabelFromWidget d1 )
                            (map fst $ init typesAndDetails)
    scnSem <-  mapM (G.radioButtonNewWithLabelFromWidget d2) [" SCANNER Data "," SCRIM Data "]
    let ontoggle butt = G.on butt G.toggled $ do
                            G.toggleButtonGetActive butt >>= \b ->
                             --- need special case for RCI
                             if b then
                                  G.buttonGetLabel butt >>=
                                    (\str ->
                                          case find ((== str) . fst) typesAndDetails  of
                                            Nothing -> return ()
                                            Just (_,lst) -> do
                                                clearAdd comboRef detailsCombo (map display lst)
                                                modifyIORef detailsListRef (\(a,b,_) -> (a,b,lst))
                                                let profileFile = "./mmlTdsFiles/Profile/currProfile.txt"
                                                L.writeFile profileFile (L.pack str)
                                    )
                             else
                                return ()
    mapM ontoggle condTypes
    ------------------------------------------------------------------------------------
    --- need to desensitive some stuff when SCRIM is selected
    let desensetiveForScrim butt = G.on butt G.toggled $ do
                                     G.toggleButtonGetActive butt >>= \b ->
                                        if b then do
                                            mapM_ (flip G.widgetSetSensitive False) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCRIM)
                                        else do
                                            mapM_ (flip G.widgetSetSensitive True) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCANNER)
    desensetiveForScrim (scnSem !! 1)

    ------------------------------------------------------------------------------------
    -- The operation we want here is to opena a dialog with options to remove
    -- entries from the list. Either indivdually selected items or all items can
    -- be removed from the list
    G.on clrButt G.buttonActivated $
        openEditDialog comboRef detailsCombo detailsListRef dispBuffer
    ---------------- PACKING ------------------------------------------------
    G.boxPackStart listsVBox optsBox G.PackNatural 5
    G.boxPackStart listsVBox (vBoxesWithLabels !! 0) G.PackNatural 5
    G.boxPackStart listsVBox entryTable G.PackNatural 5
    G.boxPackStart listsVBox hsep1 G.PackNatural 5
    --G.boxPackStart listsVBox schmAndClass G.PackNatural 2
    ---
    G.boxPackStart listsVBox hsep G.PackNatural 5
    mapM_ (\b -> G.boxPackStart buttsVBox b G.PackNatural 2) [analButton,previewButt ]
    mapM_ (\b -> G.boxPackEnd buttsVBox b G.PackNatural 4) [addButton,clrButt]
    -- put the options here
    G.boxPackStart listsVBox buttsVBox G.PackGrow 0
    --
    G.boxPackStart mainVBox topHBox G.PackNatural 6
    ------------- the bottom of the left pane -----------------------------------------.
    --- the left side has a frame highlighting the selected condition
    ---- the right the progress log
    -------- first get the table for the selected conditions. The handles for adding
    ---- this comes from the main display?
    [selectedConditions, progressLog] <- sequence $ replicate 2 G.frameNew
    G.set progressLog [G.frameLabel G.:= " Progress log" ]
    G.set selectedConditions [G.frameLabel G.:= " Selected conditions" ]
    G.containerAdd progressLog scrwin
    G.containerAdd selectedConditions selectedCondsTable
    -- tableWithWidgetList isVertical  widgets homo spacing
    displayLogs <- tableWithWidgetList False  [selectedConditions, progressLog] True 5
    G.boxPackStart  bottomHBox displayLogs G.PackGrow 6
    G.boxPackStart mainVBox bottomHBox  G.PackGrow 6
    -------------------------
    --G.widgetModifyBg mainVBox G.StateActive (G.Color 190 190 190)
    let rbutts = condTypes ++ scnSem
    -- check what has been extracted already
    --checkIfExtracted logProgress
    G.on previewButt G.buttonActivated $ do
        -- extract and align the file, bot do not analyse
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,False)
    --
    G.on analButton G.buttonActivated $ do
        --let btyp = (analButton,True)
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,True)
    ------------------------------------------------------------------------------------
    let pParms = PreviewParms logProgress yearsEntry distEntry negativeSlopes sl
    readIORef detailsListRef >>= \(sels,pms,_) -> do
        return (mainVBox, Nothing, rbutts, fileEntry,pParms)
    where
        getSelectedConditionsTable = do
            labels <- mapM (G.labelNew . Just) [" No."," Description "]
            headBox <- G.hBoxNew False 1
            displayBox <- G.vBoxNew False 1
            ---
            G.boxPackStart headBox (labels !! 0)  G.PackNatural 1
            G.boxPackEnd headBox (labels !! 1)  G.PackGrow 1
            G.vSeparatorNew >>= \sep -> G.boxPackEnd headBox sep  G.PackNatural 0
            ---
            (display, dispBuffer) <- makeScrolledEntryArea  HScroll False False
            G.boxPackStart displayBox headBox G.PackNatural 1
            G.boxPackStart displayBox display G.PackGrow 1
            return (displayBox , dispBuffer)
            --G.tableAttachDefaults entryTable (entryPairs !! 0) 0 1 0 1
        --
        validateFilePath str =
            let string = "The name entered is not a valid file path." in
                if isValid str then Nothing else (Just string)
        -- countRef
        write2Buffer tbuffer wrt string  = do
            let wrds = words string
            if not (null wrds) && head wrds == "Finished" then
                G.textBufferGetEndIter tbuffer >>= \iter ->
                    G.textBufferInsert tbuffer iter (string ++"\n")
            else
                wrt string
        -- handle for analayis and Extraction ---  extract, analyse, extNorAnl
        handleForAnalAndExtract extAnal fileEnt deatilsLstRef dataTypRef wrt butType = do
            extnl <- readIORef extAnal
            let (button,isAnal) = butType
            case extnl of
                Nothing -> do
                -- Just _  -
                    --let senstize = G.widgetSetSensitive button True
                    --let deSenstize = G.widgetSetSensitive button False
                    let reSetFlag = do
                                        modifyIORef  extAnal (\_ -> Nothing)
                                        check <- readIORef extAnal
                                        print (show check)
                    filePath <- G.entryGetText fileEnt
                    case validateFilePath filePath of
                        Just errString  ->
                            runMsgDialog Nothing errString Error
                        Nothing  -> do
                            -- forkIO $ copty file to the files folder. Useful for extracting HMDIF
                            --(sl,_,_) <- readIORef detailsListRef
                            (sels,pms,_) <- readIORef deatilsLstRef
                            if null sels then
                                runMsgDialog Nothing "You have not selected any parameter investigate" Error
                            else do
                                -- parse the file for scrim or scanner
                                fileOk <-  readIORef dataTypRef >>= parseFile filePath -- fKind
                                case fileOk of
                                    Nothing -> do
                                    ----
                                        let line chr = '\n' : replicate 40 chr ++"\n"
                                        let toAnalyse (sc, (ye,dst,ns)) = display sc ++ ": \n\t-\
                                            \ Maint. frequency: "++show ye++"\
                                            \ years; \n\t- Dist. between maint. works: "++ show dst ++ "\
                                            \ Km; \n\t- Negative slopes: "++ show ns ++ line '-'
                                        let list = concatMap toAnalyse $ zip sels pms
                                        let st = "You have choosen to Analyse the following:"++ line '='
                                        let qt   = line '=' ++ "\n\nDo you wish to proceed? "
                                        ----- need a decision dialog here with the stuff being done
                                        let labelInfo = "Running MML2DS on the selected conditions. "
                                        --- set up the progress buffer ------------------------
                                        let runAnalysis = do
                                            g <- newStdGen
                                            let anF dp ye dst ns dk n m = exF dp ye dst ns dk n m
                                            --let anF tds = mml2DsGD g tds
                                            -- mml2DsGD g dp ye dst ns dk n m wrt
                                            --let exF _ _ _ _ _ _ _   = return (([],[]) :: ([(OModel, ([Double], [Int]))], [Int]))
                                            let analFun = if isAnal then anF else exF
                                            runAnalysisFromWindow filePath wrt analFun $ zip sels pms -- >> reSetFlag
                                        wrt labelInfo -- show what process is being done
                                        modifyIORef  extAnal (\_ -> Just isAnal)
                                        forkProcess (Just labelInfo) wrt runAnalysis (Just reSetFlag)
                                        -- deSenstize
                                    Just errString ->  runMsgDialog Nothing errString Error
                Just ea -> do
                    -- show a message if analysis or extract is clicked when a process is already running
                    let exOrAn = if ea then  "analysis"  else "extraction"
                    let errString = "An "++exOrAn++ " process is currently running, which \
                                    \ muct be completed before you can proceed with this action."
                    runMsgDialog Nothing errString Error
            where
                        exF :: Int -> Double -> Double -> Bool -> Int
                                -> Int -> Int -> [[Double]]
                                -> IO [([(OModel, ([Double], [Int]))], [Int])]
                        exF  _ _ _ _ _ _ _ _ = return []
                        ---


-------------------------------------------------------------------------------------
-- test: running the analysis on all the data from the analyisis window
-------------------------------------------------------------------------------------
type Data = [[Double]]
runAnalysisFromWindow :: String ->
    (String -> IO ()) ->
    --(Double -> Double -> Bool -> Data -> IO ([([(OModel, ([Double], [Int]))], [Int])])) ->
    (   Int    -> -- search depth
            Double -> -- range in years
            Double -> -- range in distance
            --g      -> -- random starting value
            Bool   -> -- ignore negative slopes
            --Int    -> -- the maximum number of possible cuts for the segment. See QueryDialog for details
            Int    -> -- the maximum number of chains to align
            Int    -> -- the minimum number of chains to align
            Int    -> -- the minimum number of points to trend
            [[Double]] ->
            IO [([(OModel, ([Double], [Int]))], [Int]) ]) ->
    [(Defect,(Double,Double,Bool))] -> IO ()
runAnalysisFromWindow fileName write2B anlF options = do
     let runAnalysis (sc ,(yr, ds, ns)) = -- (anlF yr ds ns) -- (\a -> anlF a yr ds ns)
            bs2HMDIF2bs_aux Nothing fileName write2B   Nothing Rapid (show sc, scode2align sc) (5,35) Nothing
     mapM_ runAnalysis options
     return () -- force a return

------------------------------------------------------------------------------------}
--
------------------------------------------------------------------------------------
analysisBoxForAFrame ::  Bool -> [G.RadioButton] ->
     G.Entry  -> [G.VBox] ->   IO G.VBox
analysisBoxForAFrame tf rbutts fe boxes = do
    aBox <- G.vBoxNew False 5
    selectBox <- getSelectBox tf rbutts fe -- this comes from another function
    detailsFrame <- G.frameNew
    G.set detailsFrame [G.frameLabel G.:= " Condition parameters" ]
    table <- tableWithWidgetList False boxes False 2
    --table <- hPanedArea (boxes !! 0) (boxes !! 1) 100
    G.containerAdd detailsFrame selectBox
    G.boxPackStart aBox detailsFrame G.PackNatural 5
    G.boxPackStart aBox table G.PackGrow 2 -- detailsFrame
    return aBox
    --
    where
        getSelectBox :: Bool -> [G.RadioButton] -> G.Entry  -> IO G.HBox
        getSelectBox sE rbutts fileEntry = do
            [thbox,entryBox, tablesBox] <- sequence $ replicate 3 (G.hBoxNew False 2)
            browseButton <- G.buttonNewWithLabel " Load data file "
            --- pack the entry box
            G.boxPackEnd entryBox fileEntry G.PackGrow 4
            G.boxPackStart entryBox browseButton G.PackNatural 2
            G.on browseButton G.buttonActivated $ do
                fileBrowser (Just fileEntry) >>= G.dialogRun  >>= \_ -> return () -- ) >> return ()
            --- put the condition chooser in a box
            let n = length rbutts
            let (condTypes, scnSem) = splitAt (n-2) rbutts
            condBox <- tableWithWidgetList False condTypes False 3
            vButtonTable <- tableWithWidgetList True scnSem True 3
            G.vSeparatorNew >>= \sep -> do
                sep1 <- G.vSeparatorNew
                G.boxPackStart tablesBox  sep1 G.PackNatural 0
                G.boxPackStart tablesBox  vButtonTable G.PackNatural 8
                G.boxPackStart tablesBox  sep G.PackNatural 0
                G.boxPackStart tablesBox  condBox G.PackGrow 5
                --
                --G.containerAdd tablesFrame tablesBox
                if sE then do
                    G.boxPackStart thbox  entryBox G.PackGrow 2
                    G.boxPackStart thbox  tablesBox G.PackGrow 0
                else do
                    G.boxPackStart thbox  tablesBox G.PackGrow 2
                    G.boxPackStart thbox  entryBox G.PackGrow 0
            --
            --detailsFrame <- G.frameNew
            return thbox
   --}
{-
--------------------------------------------------------------------------------------------------
--    Dialog to initialize the network level analyis and related dialiogos and datatypes
--------------------------------------------------------------------------------------------------
--- the maybe here should be a pair of tracking panes
globalAnalysisTop :: Maybe G.Window ->
    Maybe (IORef [Road]) ->
    IO (G.VBox, Maybe AWin,[G.RadioButton], G.Entry , PreviewParms)
globalAnalysisTop  mwin strAndChn = do
    [mainVBox,listsVBox] <- sequence $ replicate 2 (G.vBoxNew False 1)
    [bottomHBox,topHBox, -- condsVBox, topHBox,bottomOBox,
        buttsVBox] <- sequence $ replicate 3 (G.hBoxNew False 1)
    comboList <- sequence $ replicate 5 G.comboBoxNewText
    vsep   <- G.vSeparatorNew
    [hsep, hsep1, hsep2]   <- sequence $ replicate 3 G.hSeparatorNew
    [yearsEntry, distEntry, fileEntry] <- sequence $ replicate 3 G.entryNew
    -- fileEntry is the entry for the file Path. set the size of the entry
    G.widgetSetSizeRequest fileEntry 360 (-1)
    -------------------------------------------------------------------
    prevAnalFrame <- G.frameNew
    -- condTypes
    ------------------------------------------------------------------------------------
    -- the display window
    -- the progress and display buffers
    (scrwin,progressBuffer) <- makeScrolledEntryArea BScroll False True
    G.widgetSetSizeRequest scrwin 60 (-1)
    -------- and updating chains will be added here
    (selectedCondsTable, dispBuffer) <- getSelectedConditionsTable
    ---
    let logProgress   = updateBufferAtEnd progressBuffer
    let add2SeletList = updateBufferAtEnd dispBuffer
    ----- check for extracted conditons
    checkIfExtracted False True logProgress
    -------------------------------------------------------------------
    G.set prevAnalFrame [G.frameLabel G.:= " Condition attribures" ]
    G.containerAdd prevAnalFrame listsVBox -- listsVBox
    G.boxPackStart topHBox prevAnalFrame G.PackGrow 6
    -------------------------------------------------------------------
    mapM_ (\ent -> do
                G.entrySetWidthChars ent 6
                G.entrySetMaxLength ent 6) [yearsEntry, distEntry]
    let [detailsCombo,rNameCombo,rClassCombo,rCodeCombo,srCodeCombo] = comboList
    -- fillToMaxLegth :: [String] -> [String]mapM (G.labelNew . Just)
    let comboNames = ["Road Class: ", "Road Name: ", "SCANNER Section Code: "," SCRIM Section Code: "]
    --mapM_ (\w -> G.miscSetAlignment w 1 0.5) comboNames
    let schms = zip (fillToMaxLegth comboNames)  [rClassCombo,rNameCombo,rCodeCombo,srCodeCombo]
    --let labelAndWidget m a b = labelLeftofWidget a b m
    comboBoxesWithLables <- mapM (\(l,w) -> labelLeftofWidget l w False ) (take 2 schms)
    comboBoxesWithLables1 <- mapM (\(l,w) -> labelLeftofWidget l w False ) (drop 2 schms)
    -- create table
    row1 <- tableWithWidgetList False comboBoxesWithLables False 2
    row2 <- tableWithWidgetList False comboBoxesWithLables1 False 2
    --schmAndClass <- tableWithWidgetList True [row1,row2] True 2
    ------------------------------------ }
    comboRef <- newIORef [] --- the a record to toggle the condition details
    --roadConditionRef
    --- selected,
    detailsListRef <- newIORef ([],[],[])
    advancedRef <- newIORef ([],Nothing)
    dataTypeRef <- newIORef SCANNER -- toggles the curreltly selected data type
    countRef <- newIORef 1 -- a counter ref track what is happings
    rNameRef <- newIORef []
    extractAnal <- newIORef Nothing --- flag to toggle extraction or analysys
    ------------------------------------
    let comboLabels = [" Condition Detail: "]
    let comboLabelPairs = zip comboLabels comboList
    vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    ---
    [rcl,rsc] <-  mapM G.radioButtonNewWithLabel ["Road Class","Section Code"]
    G.radioButtonSetGroup rcl rsc
    --mapM_ (\b -> G.boxPackEnd (vBoxesWithLabels !! 0) b G.PackNatural 6) [rcl,rsc]
    -------------------------------------------------------------------------------
    ---- fork the population of the roads, etc
    ---  We will need to put each road class in a separate file. This wouuld be done when
    ---  When the details of the roas is added
    -- desensetise the combos :
    mapM_ (flip G.widgetSetSensitive False) (map snd schms)
    rtypes <- getRoadClasses >>= return . filter (isAlpha . snd)
    let roadTypes =  map snd $ nubBy (\a b -> snd a == snd b) rtypes
    ----- extract the road classes
    let getClasses = mapM_ (G.comboBoxAppendText rClassCombo) $ map ( :"-roads") roadTypes
    --let getNames   = mapM_ (G.comboBoxAppendText rNameRef) $ map L.unpack rNames
    --forkIO $ mapM_ (G.comboBoxAppendText rCodeCombo) $ map (\(a,_,_) -> L.unpack a) secAndTypes
    -- clearAdd cRef combo list
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    rCodesComboRef <- newIORef [] --- the a record to toggle the condition details
    roadClassAdded <- newIORef False
    {--- fix this
    let getCodesFromClass = do
        index <- G.comboBoxGetActive rClassCombo
        if index >= 0 then  do
            let !codes = [bs | (bs,c) <- rtypes, c == (roadTypes !! index)]
            clearAdd rCodesComboRef rCodeCombo  $ map L.unpack codes --
        else  return ()
    --}
    G.on rClassCombo G.changed $ do
          rclsAdded <- readIORef roadClassAdded
          index <- G.comboBoxGetActive rClassCombo
          if rclsAdded then do
              let des = "Extracting classes for "++[roadTypes !! index]++"-roads"
              logProgress (des ++ " ... ")
              -- forkProcess (Just des) logProgress getCodesFromClass Nothing
          else  do
              let rtyp = roadTypes !! index
              let mkRN1 (a,b,c) = L.unpack c
              let mkSC1 (a,b,c) = L.unpack b
              logProgress ([rtyp] ++"-roads selected")
              rname <- getRoadNamesAndSections (map fst $ filter ((== rtyp) . snd) rtypes) -- >>= return $ map mkSt1
              clearAdd rNameRef rNameCombo (map mkRN1 rname)
              clearAdd rCodesComboRef rCodeCombo (map mkSC1 rname)
              G.widgetSetSensitive rNameCombo True
    --sensetize the combos once the road classes have been extracted
    forkProcess Nothing logProgress getClasses
                        (Just $ mapM_ (flip G.widgetSetSensitive True) [rClassCombo,rCodeCombo])

    --forkProcess Nothing (updateBufferAtEnd progressBuffer) getNames
    --                    (Just $ mapM_ (flip G.widgetSetSensitive True) [rNameCombo,rCodeCombo])
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    -- clearAdd comboRef detailsCombo (map display lst)
    --- update the road class names,codes and section codes upon a election of a road class
    -------------------------------------------------------------------------
    [addButton,analButton,previewButt,clrButt] <- mapM G.buttonNewWithLabel
                                                                [" Add condition details ",
                                                                 " Analyse ", " Extract ",
                                                                 " Edit List "]
    --advOptions <- advancedOptionsWin -- (Just advancedRef)
    -- file entry box vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    let entryLabels = ["  Average maintenance frequency in years: ",
                       "  Average treatment length in kilometers: "]
    let entryPairs = zip entryLabels [yearsEntry, distEntry]
    entryTable <- mapM (\(l,w) -> labelLeftofWidget l w True) entryPairs >>= \eb ->
                        tableWithWidgetList False eb False 10
                   --     [yearsEntry, distEntry]
    -- use the dummy do that none will be set on start up
    dummy  <-  G.radioButtonNew -- WithLabel "
    [nl, sl]  <- mapM G.radioButtonNewWithLabel [" Network Level Analysis "," Scheme/road Level Analysis "]
    G.radioButtonSetGroup dummy nl
    G.radioButtonSetGroup nl sl
    ---
    ---
    --- negative slopes
    negativeSlopes  <- G.checkButtonNew -- WithLabel "
    optsBox <- labelLeftofWidgetE' "Include negative slopes " 1 negativeSlopes True
    --
    mapM_ (\w -> G.boxPackStart optsBox w G.PackGrow 2) [nl,sl]
    --G.boxPackEnd optsBox negativeSlopes' G.PackGrow 2
    -------------------------------------------------------------------------------------
    G.on addButton G.buttonActivated $ do
        -- need here: read inout parameter file
        [str1,str2] <- mapM G.entryGetText [yearsEntry, distEntry]
        negSlope <- G.toggleButtonGetActive negativeSlopes
        -- return () -- temporary
        --
        case (validateEntries [str1,str2] ["years","distance"]) of
            Left [e1,e2] -> do
                index <- G.comboBoxGetActive detailsCombo -- >>= \index ->
                if index >= 0 then do
                    (selected,_,dlist) <- readIORef detailsListRef -- >>=  \ ->  do
                    let sel = (dlist !! index)
                    let str = (display sel) -- ++ (" yrs: "++str1 ++ " dist: "++str2)
                    let message = "You have already added \'" ++ display sel  ++ "\' to\
                                  \ the list of selected conditions."
                    --
                    if sel `elem` selected then
                        runMsgDialog Nothing message Info
                    else do
                        let pm = (fromIntegral e1, fromIntegral e2,negSlope)
                        add2SeletList str
                        modifyIORef detailsListRef (\(a,ps,b) -> (sel : a,pm:ps,b))
                        -- clear the entries and neg slope
                        mapM_ (\ent -> G.entrySetText ent "") [yearsEntry, distEntry]
                        G.toggleButtonSetActive negativeSlopes False
                else
                    runMsgDialog Nothing "Negative index at condition details combo box" Error
            Right string -> runMsgDialog Nothing string Error
    ------------------------------------------------------------------------------------ }
    ---- the scanner or scrim radio butttons
    [d1,d2] <- mapM (\st -> G.radioButtonNewWithLabel st) ["", ""]
    condTypes <- mapM (G.radioButtonNewWithLabelFromWidget d1 )
                            (map fst $ init typesAndDetails)
    scnSem <-  mapM (G.radioButtonNewWithLabelFromWidget d2) [" SCANNER Data "," SCRIM Data "]
    let ontoggle butt = G.on butt G.toggled $ do
                            G.toggleButtonGetActive butt >>= \b ->
                             --- need special case for RCI
                             if b then
                                  G.buttonGetLabel butt >>=
                                    (\str ->
                                          case find ((== str) . fst) typesAndDetails  of
                                            Nothing -> return ()
                                            Just (_,lst) -> do
                                                clearAdd comboRef detailsCombo (map display lst)
                                                modifyIORef detailsListRef (\(a,b,_) -> (a,b,lst))
                                                let profileFile = "./mmlTdsFiles/Profile/currProfile.txt"
                                                L.writeFile profileFile (L.pack str)
                                    )
                             else
                                return ()
    mapM ontoggle condTypes
    ------------------------------------------------------------------------------------
    --- need to desensitive some stuff when SCRIM is selected
    let desensetiveForScrim butt = G.on butt G.toggled $ do
                                     G.toggleButtonGetActive butt >>= \b ->
                                        if b then do
                                            mapM_ (flip G.widgetSetSensitive False) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCRIM)
                                        else do
                                            mapM_ (flip G.widgetSetSensitive True) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCANNER)
    desensetiveForScrim (scnSem !! 1)

    ------------------------------------------------------------------------------------
    -- The operation we want here is to opena a dialog with options to remove
    -- entries from the list. Either indivdually selected items or all items can
    -- be removed from the list
    G.on clrButt G.buttonActivated $
        openEditDialog comboRef detailsCombo detailsListRef dispBuffer
    ---------------- PACKING ------------------------------------------------
    G.boxPackStart listsVBox optsBox G.PackNatural 5
    G.boxPackStart listsVBox (vBoxesWithLabels !! 0) G.PackNatural 5
    G.boxPackStart listsVBox entryTable G.PackNatural 5
    G.boxPackStart listsVBox hsep1 G.PackNatural 5
    --G.boxPackStart listsVBox schmAndClass G.PackNatural 2
    ---
    G.boxPackStart listsVBox hsep G.PackNatural 5
    mapM_ (\b -> G.boxPackStart buttsVBox b G.PackNatural 2) [analButton,previewButt ]
    mapM_ (\b -> G.boxPackEnd buttsVBox b G.PackNatural 4) [addButton,clrButt]
    -- put the options here
    G.boxPackStart listsVBox buttsVBox G.PackGrow 0
    --
    G.boxPackStart mainVBox topHBox G.PackNatural 6
    ------------- the bottom of the left pane -----------------------------------------.
    --- the left side has a frame highlighting the selected condition
    ---- the right the progress log
    -------- first get the table for the selected conditions. The handles for adding
    ---- this comes from the main display?
    [selectedConditions, progressLog] <- sequence $ replicate 2 G.frameNew
    G.set progressLog [G.frameLabel G.:= " Progress log" ]
    G.set selectedConditions [G.frameLabel G.:= " Selected conditions" ]
    G.containerAdd progressLog scrwin
    G.containerAdd selectedConditions selectedCondsTable
    -- tableWithWidgetList isVertical  widgets homo spacing
    displayLogs <- tableWithWidgetList False  [selectedConditions, progressLog] True 5
    G.boxPackStart  bottomHBox displayLogs G.PackGrow 6
    G.boxPackStart mainVBox bottomHBox  G.PackGrow 6
    -------------------------
    --G.widgetModifyBg mainVBox G.StateActive (G.Color 190 190 190)
    let rbutts = condTypes ++ scnSem
    -- check what has been extracted already
    --checkIfExtracted logProgress
    G.on previewButt G.buttonActivated $ do
        -- extract and align the file, bot do not analyse
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,False)
    --
    G.on analButton G.buttonActivated $ do
        --let btyp = (analButton,True)
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,True)
    ------------------------------------------------------------------------------------
    let pParms = PreviewParms logProgress yearsEntry distEntry negativeSlopes sl
    readIORef detailsListRef >>= \(sels,pms,_) -> do
        return (mainVBox, Nothing, rbutts, fileEntry,pParms)
    where
        getSelectedConditionsTable = do
            labels <- mapM (G.labelNew . Just) [" No."," Description "]
            headBox <- G.hBoxNew False 1
            displayBox <- G.vBoxNew False 1
            ---
            G.boxPackStart headBox (labels !! 0)  G.PackNatural 1
            G.boxPackEnd headBox (labels !! 1)  G.PackGrow 1
            G.vSeparatorNew >>= \sep -> G.boxPackEnd headBox sep  G.PackNatural 0
            ---
            (display, dispBuffer) <- makeScrolledEntryArea  HScroll False False
            G.boxPackStart displayBox headBox G.PackNatural 1
            G.boxPackStart displayBox display G.PackGrow 1
            return (displayBox , dispBuffer)
            --G.tableAttachDefaults entryTable (entryPairs !! 0) 0 1 0 1
        --
        validateFilePath str =
            let string = "The name entered is not a valid file path." in
                if isValid str then Nothing else (Just string)
        -- countRef
        write2Buffer tbuffer wrt string  = do
            let wrds = words string
            if not (null wrds) && head wrds == "Finished" then
                G.textBufferGetEndIter tbuffer >>= \iter ->
                    G.textBufferInsert tbuffer iter (string ++"\n")
            else
                wrt string
        -- handle for analayis and Extraction ---  extract, analyse, extNorAnl
        handleForAnalAndExtract extAnal fileEnt deatilsLstRef dataTypRef wrt butType = do
            extnl <- readIORef extAnal
            let (button,isAnal) = butType
            case extnl of
                Nothing -> do
                -- Just _  -
                    --let senstize = G.widgetSetSensitive button True
                    --let deSenstize = G.widgetSetSensitive button False
                    let reSetFlag = do
                                        modifyIORef  extAnal (\_ -> Nothing)
                                        check <- readIORef extAnal
                                        print (show check)
                    filePath <- G.entryGetText fileEnt
                    case validateFilePath filePath of
                        Just errString  ->
                            runMsgDialog Nothing errString Error
                        Nothing  -> do
                            -- forkIO $ copty file to the files folder. Useful for extracting HMDIF
                            --(sl,_,_) <- readIORef detailsListRef
                            (sels,pms,_) <- readIORef deatilsLstRef
                            if null sels then
                                runMsgDialog Nothing "You have not selected any parameter investigate" Error
                            else do
                                -- parse the file for scrim or scanner
                                fileOk <-  readIORef dataTypRef >>= parseFile filePath -- fKind
                                case fileOk of
                                    Nothing -> do
                                    ----
                                        let line chr = '\n' : replicate 40 chr ++"\n"
                                        let toAnalyse (sc, (ye,dst,ns)) = display sc ++ ": \n\t-\
                                            \ Maint. frequency: "++show ye++"\
                                            \ years; \n\t- Dist. between maint. works: "++ show dst ++ "\
                                            \ Km; \n\t- Negative slopes: "++ show ns ++ line '-'
                                        let list = concatMap toAnalyse $ zip sels pms
                                        let st = "You have choosen to Analyse the following:"++ line '='
                                        let qt   = line '=' ++ "\n\nDo you wish to proceed? "
                                        ----- need a decision dialog here with the stuff being done
                                        let labelInfo = "Running MML2DS on the selected conditions. "
                                        --- set up the progress buffer ------------------------
                                        let runAnalysis = do
                                            g <- newStdGen
                                            let anF dp ye dst ns dk n m = exF dp ye dst ns dk n m
                                            --let anF tds = mml2DsGD g tds
                                            -- mml2DsGD g dp ye dst ns dk n m wrt
                                            --let exF _ _ _ _ _ _ _   = return (([],[]) :: ([(OModel, ([Double], [Int]))], [Int]))
                                            let analFun = if isAnal then anF else exF
                                            runAnalysisFromWindow filePath wrt analFun $ zip sels pms -- >> reSetFlag
                                        wrt labelInfo -- show what process is being done
                                        modifyIORef  extAnal (\_ -> Just isAnal)
                                        forkProcess (Just labelInfo) wrt runAnalysis (Just reSetFlag)
                                        -- deSenstize
                                    Just errString ->  runMsgDialog Nothing errString Error
                Just ea -> do
                    -- show a message if analysis or extract is clicked when a process is already running
                    let exOrAn = if ea then  "analysis"  else "extraction"
                    let errString = "An "++exOrAn++ " process is currently running, which \
                                    \ muct be completed before you can proceed with this action."
                    runMsgDialog Nothing errString Error
            where
                        exF :: Int -> Double -> Double -> Bool -> Int
                                -> Int -> Int -> [[Double]]
                                -> IO [([(OModel, ([Double], [Int]))], [Int])]
                        exF  _ _ _ _ _ _ _ _ = return []
                        ---


-------------------------------------------------------------------------------------
-- test: running the analysis on all the data from the analyisis window
-------------------------------------------------------------------------------------
type Data = [[Double]]
runAnalysisFromWindow :: String ->
    (String -> IO ()) ->
    --(Double -> Double -> Bool -> Data -> IO ([([(OModel, ([Double], [Int]))], [Int])])) ->
    (   Int    -> -- search depth
            Double -> -- range in years
            Double -> -- range in distance
            --g      -> -- random starting value
            Bool   -> -- ignore negative slopes
            --Int    -> -- the maximum number of possible cuts for the segment. See QueryDialog for details
            Int    -> -- the maximum number of chains to align
            Int    -> -- the minimum number of chains to align
            Int    -> -- the minimum number of points to trend
            [[Double]] ->
            IO [([(OModel, ([Double], [Int]))], [Int]) ]) ->
    [(Defect,(Double,Double,Bool))] -> IO ()
runAnalysisFromWindow fileName write2B anlF options = do
     let runAnalysis (sc ,(yr, ds, ns)) = -- (anlF yr ds ns) -- (\a -> anlF a yr ds ns)
            bs2HMDIF2bs_aux Nothing fileName write2B   Nothing Rapid (show sc, scode2align sc) (5,35) Nothing
     mapM_ runAnalysis options
     return () -- force a return

------------------------------------------------------------------------------------}
--
------------------------------------------------------------------------------------
analysisBoxForAFrame tf rbutts fe boxes = do
    aBox <- G.vBoxNew False 5
    selectBox <- getSelectBox tf rbutts fe -- this comes from another function
    detailsFrame <- G.frameNew
    G.set detailsFrame [G.frameLabel G.:= " Condition parameters" ]
    table <- tableWithWidgetList False boxes False 2
    --table <- hPanedArea (boxes !! 0) (boxes !! 1) 100
    G.containerAdd detailsFrame selectBox
    G.boxPackStart aBox detailsFrame G.PackNatural 5
    G.boxPackStart aBox table G.PackGrow 2 -- detailsFrame
    return aBox
    --
    where
        getSelectBox :: Bool -> [G.RadioButton] -> G.Entry  -> IO G.HBox
        getSelectBox sE rbutts fileEntry = do
            [thbox,entryBox, tablesBox] <- sequence $ replicate 3 (G.hBoxNew False 2)
            browseButton <- G.buttonNewWithLabel " Load data file "
            --- pack the entry box
            G.boxPackEnd entryBox fileEntry G.PackGrow 4
            G.boxPackStart entryBox browseButton G.PackNatural 2
            G.on browseButton G.buttonActivated $ do
                fileBrowser (Just fileEntry) >>= G.dialogRun  >>= \_ -> return () -- ) >> return ()
            --- put the condition chooser in a box
            let n = length rbutts
            let (condTypes, scnSem) = splitAt (n-2) rbutts
            condBox <- tableWithWidgetList False condTypes False 3
            vButtonTable <- tableWithWidgetList True scnSem True 3
            G.vSeparatorNew >>= \sep -> do
                sep1 <- G.vSeparatorNew
                G.boxPackStart tablesBox  sep1 G.PackNatural 0
                G.boxPackStart tablesBox  vButtonTable G.PackNatural 8
                G.boxPackStart tablesBox  sep G.PackNatural 0
                G.boxPackStart tablesBox  condBox G.PackGrow 5
                --
                --G.containerAdd tablesFrame tablesBox
                if sE then do
                    G.boxPackStart thbox  entryBox G.PackGrow 2
                    G.boxPackStart thbox  tablesBox G.PackGrow 0
                else do
                    G.boxPackStart thbox  tablesBox G.PackGrow 2
                    G.boxPackStart thbox  entryBox G.PackGrow 0
            --
            --detailsFrame <- G.frameNew
            return thbox
   --}
{-
--------------------------------------------------------------------------------------------------
--    Dialog to initialize the network level analyis and related dialiogos and datatypes
--------------------------------------------------------------------------------------------------
--- the maybe here should be a pair of tracking panes
globalAnalysisTop :: Maybe G.Window ->
    Maybe (IORef [Road]) ->
    IO (G.VBox, Maybe AWin,[G.RadioButton], G.Entry , PreviewParms)
globalAnalysisTop  mwin strAndChn = do
    [mainVBox,listsVBox] <- sequence $ replicate 2 (G.vBoxNew False 1)
    [bottomHBox,topHBox, -- condsVBox, topHBox,bottomOBox,
        buttsVBox] <- sequence $ replicate 3 (G.hBoxNew False 1)
    comboList <- sequence $ replicate 5 G.comboBoxNewText
    vsep   <- G.vSeparatorNew
    [hsep, hsep1, hsep2]   <- sequence $ replicate 3 G.hSeparatorNew
    [yearsEntry, distEntry, fileEntry] <- sequence $ replicate 3 G.entryNew
    -- fileEntry is the entry for the file Path. set the size of the entry
    G.widgetSetSizeRequest fileEntry 360 (-1)
    -------------------------------------------------------------------
    prevAnalFrame <- G.frameNew
    -- condTypes
    ------------------------------------------------------------------------------------
    -- the display window
    -- the progress and display buffers
    (scrwin,progressBuffer) <- makeScrolledEntryArea BScroll False True
    G.widgetSetSizeRequest scrwin 60 (-1)
    -------- and updating chains will be added here
    (selectedCondsTable, dispBuffer) <- getSelectedConditionsTable
    ---
    let logProgress   = updateBufferAtEnd progressBuffer
    let add2SeletList = updateBufferAtEnd dispBuffer
    ----- check for extracted conditons
    checkIfExtracted False True logProgress
    -------------------------------------------------------------------
    G.set prevAnalFrame [G.frameLabel G.:= " Condition attribures" ]
    G.containerAdd prevAnalFrame listsVBox -- listsVBox
    G.boxPackStart topHBox prevAnalFrame G.PackGrow 6
    -------------------------------------------------------------------
    mapM_ (\ent -> do
                G.entrySetWidthChars ent 6
                G.entrySetMaxLength ent 6) [yearsEntry, distEntry]
    let [detailsCombo,rNameCombo,rClassCombo,rCodeCombo,srCodeCombo] = comboList
    -- fillToMaxLegth :: [String] -> [String]mapM (G.labelNew . Just)
    let comboNames = ["Road Class: ", "Road Name: ", "SCANNER Section Code: "," SCRIM Section Code: "]
    --mapM_ (\w -> G.miscSetAlignment w 1 0.5) comboNames
    let schms = zip (fillToMaxLegth comboNames)  [rClassCombo,rNameCombo,rCodeCombo,srCodeCombo]
    --let labelAndWidget m a b = labelLeftofWidget a b m
    comboBoxesWithLables <- mapM (\(l,w) -> labelLeftofWidget l w False ) (take 2 schms)
    comboBoxesWithLables1 <- mapM (\(l,w) -> labelLeftofWidget l w False ) (drop 2 schms)
    -- create table
    row1 <- tableWithWidgetList False comboBoxesWithLables False 2
    row2 <- tableWithWidgetList False comboBoxesWithLables1 False 2
    --schmAndClass <- tableWithWidgetList True [row1,row2] True 2
    ------------------------------------ }
    comboRef <- newIORef [] --- the a record to toggle the condition details
    --roadConditionRef
    --- selected,
    detailsListRef <- newIORef ([],[],[])
    advancedRef <- newIORef ([],Nothing)
    dataTypeRef <- newIORef SCANNER -- toggles the curreltly selected data type
    countRef <- newIORef 1 -- a counter ref track what is happings
    rNameRef <- newIORef []
    extractAnal <- newIORef Nothing --- flag to toggle extraction or analysys
    ------------------------------------
    let comboLabels = [" Condition Detail: "]
    let comboLabelPairs = zip comboLabels comboList
    vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    ---
    [rcl,rsc] <-  mapM G.radioButtonNewWithLabel ["Road Class","Section Code"]
    G.radioButtonSetGroup rcl rsc
    --mapM_ (\b -> G.boxPackEnd (vBoxesWithLabels !! 0) b G.PackNatural 6) [rcl,rsc]
    -------------------------------------------------------------------------------
    ---- fork the population of the roads, etc
    ---  We will need to put each road class in a separate file. This wouuld be done when
    ---  When the details of the roas is added
    -- desensetise the combos :
    mapM_ (flip G.widgetSetSensitive False) (map snd schms)
    rtypes <- getRoadClasses >>= return . filter (isAlpha . snd)
    let roadTypes =  map snd $ nubBy (\a b -> snd a == snd b) rtypes
    ----- extract the road classes
    let getClasses = mapM_ (G.comboBoxAppendText rClassCombo) $ map ( :"-roads") roadTypes
    --let getNames   = mapM_ (G.comboBoxAppendText rNameRef) $ map L.unpack rNames
    --forkIO $ mapM_ (G.comboBoxAppendText rCodeCombo) $ map (\(a,_,_) -> L.unpack a) secAndTypes
    -- clearAdd cRef combo list
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    rCodesComboRef <- newIORef [] --- the a record to toggle the condition details
    roadClassAdded <- newIORef False
    {--- fix this
    let getCodesFromClass = do
        index <- G.comboBoxGetActive rClassCombo
        if index >= 0 then  do
            let !codes = [bs | (bs,c) <- rtypes, c == (roadTypes !! index)]
            clearAdd rCodesComboRef rCodeCombo  $ map L.unpack codes --
        else  return ()
    --}
    G.on rClassCombo G.changed $ do
          rclsAdded <- readIORef roadClassAdded
          index <- G.comboBoxGetActive rClassCombo
          if rclsAdded then do
              let des = "Extracting classes for "++[roadTypes !! index]++"-roads"
              logProgress (des ++ " ... ")
              -- forkProcess (Just des) logProgress getCodesFromClass Nothing
          else  do
              let rtyp = roadTypes !! index
              let mkRN1 (a,b,c) = L.unpack c
              let mkSC1 (a,b,c) = L.unpack b
              logProgress ([rtyp] ++"-roads selected")
              rname <- getRoadNamesAndSections (map fst $ filter ((== rtyp) . snd) rtypes) -- >>= return $ map mkSt1
              clearAdd rNameRef rNameCombo (map mkRN1 rname)
              clearAdd rCodesComboRef rCodeCombo (map mkSC1 rname)
              G.widgetSetSensitive rNameCombo True
    --sensetize the combos once the road classes have been extracted
    forkProcess Nothing logProgress getClasses
                        (Just $ mapM_ (flip G.widgetSetSensitive True) [rClassCombo,rCodeCombo])

    --forkProcess Nothing (updateBufferAtEnd progressBuffer) getNames
    --                    (Just $ mapM_ (flip G.widgetSetSensitive True) [rNameCombo,rCodeCombo])
    -- let schms = zip comboNames  [rNameCombo,rClassCombo,rCodeCombo,srCodeCombo]
    -- clearAdd comboRef detailsCombo (map display lst)
    --- update the road class names,codes and section codes upon a election of a road class
    -------------------------------------------------------------------------
    [addButton,analButton,previewButt,clrButt] <- mapM G.buttonNewWithLabel
                                                                [" Add condition details ",
                                                                 " Analyse ", " Extract ",
                                                                 " Edit List "]
    --advOptions <- advancedOptionsWin -- (Just advancedRef)
    -- file entry box vBoxesWithLabels <- mapM (\(st,w) -> labelLeftofWidget st w False) comboLabelPairs
    let entryLabels = ["  Average maintenance frequency in years: ",
                       "  Average treatment length in kilometers: "]
    let entryPairs = zip entryLabels [yearsEntry, distEntry]
    entryTable <- mapM (\(l,w) -> labelLeftofWidget l w True) entryPairs >>= \eb ->
                        tableWithWidgetList False eb False 10
                   --     [yearsEntry, distEntry]
    -- use the dummy do that none will be set on start up
    dummy  <-  G.radioButtonNew -- WithLabel "
    [nl, sl]  <- mapM G.radioButtonNewWithLabel [" Network Level Analysis "," Scheme/road Level Analysis "]
    G.radioButtonSetGroup dummy nl
    G.radioButtonSetGroup nl sl
    ---
    ---
    --- negative slopes
    negativeSlopes  <- G.checkButtonNew -- WithLabel "
    optsBox <- labelLeftofWidgetE' "Include negative slopes " 1 negativeSlopes True
    --
    mapM_ (\w -> G.boxPackStart optsBox w G.PackGrow 2) [nl,sl]
    --G.boxPackEnd optsBox negativeSlopes' G.PackGrow 2
    -------------------------------------------------------------------------------------
    G.on addButton G.buttonActivated $ do
        -- need here: read inout parameter file
        [str1,str2] <- mapM G.entryGetText [yearsEntry, distEntry]
        negSlope <- G.toggleButtonGetActive negativeSlopes
        -- return () -- temporary
        --
        case (validateEntries [str1,str2] ["years","distance"]) of
            Left [e1,e2] -> do
                index <- G.comboBoxGetActive detailsCombo -- >>= \index ->
                if index >= 0 then do
                    (selected,_,dlist) <- readIORef detailsListRef -- >>=  \ ->  do
                    let sel = (dlist !! index)
                    let str = (display sel) -- ++ (" yrs: "++str1 ++ " dist: "++str2)
                    let message = "You have already added \'" ++ display sel  ++ "\' to\
                                  \ the list of selected conditions."
                    --
                    if sel `elem` selected then
                        runMsgDialog Nothing message Info
                    else do
                        let pm = (fromIntegral e1, fromIntegral e2,negSlope)
                        add2SeletList str
                        modifyIORef detailsListRef (\(a,ps,b) -> (sel : a,pm:ps,b))
                        -- clear the entries and neg slope
                        mapM_ (\ent -> G.entrySetText ent "") [yearsEntry, distEntry]
                        G.toggleButtonSetActive negativeSlopes False
                else
                    runMsgDialog Nothing "Negative index at condition details combo box" Error
            Right string -> runMsgDialog Nothing string Error
    ------------------------------------------------------------------------------------ }
    ---- the scanner or scrim radio butttons
    [d1,d2] <- mapM (\st -> G.radioButtonNewWithLabel st) ["", ""]
    condTypes <- mapM (G.radioButtonNewWithLabelFromWidget d1 )
                            (map fst $ init typesAndDetails)
    scnSem <-  mapM (G.radioButtonNewWithLabelFromWidget d2) [" SCANNER Data "," SCRIM Data "]
    let ontoggle butt = G.on butt G.toggled $ do
                            G.toggleButtonGetActive butt >>= \b ->
                             --- need special case for RCI
                             if b then
                                  G.buttonGetLabel butt >>=
                                    (\str ->
                                          case find ((== str) . fst) typesAndDetails  of
                                            Nothing -> return ()
                                            Just (_,lst) -> do
                                                clearAdd comboRef detailsCombo (map display lst)
                                                modifyIORef detailsListRef (\(a,b,_) -> (a,b,lst))
                                                let profileFile = "./mmlTdsFiles/Profile/currProfile.txt"
                                                L.writeFile profileFile (L.pack str)
                                    )
                             else
                                return ()
    mapM ontoggle condTypes
    ------------------------------------------------------------------------------------
    --- need to desensitive some stuff when SCRIM is selected
    let desensetiveForScrim butt = G.on butt G.toggled $ do
                                     G.toggleButtonGetActive butt >>= \b ->
                                        if b then do
                                            mapM_ (flip G.widgetSetSensitive False) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCRIM)
                                        else do
                                            mapM_ (flip G.widgetSetSensitive True) condTypes
                                            modifyIORef dataTypeRef (\_ -> SCANNER)
    desensetiveForScrim (scnSem !! 1)

    ------------------------------------------------------------------------------------
    -- The operation we want here is to opena a dialog with options to remove
    -- entries from the list. Either indivdually selected items or all items can
    -- be removed from the list
    G.on clrButt G.buttonActivated $
        openEditDialog comboRef detailsCombo detailsListRef dispBuffer
    ---------------- PACKING ------------------------------------------------
    G.boxPackStart listsVBox optsBox G.PackNatural 5
    G.boxPackStart listsVBox (vBoxesWithLabels !! 0) G.PackNatural 5
    G.boxPackStart listsVBox entryTable G.PackNatural 5
    G.boxPackStart listsVBox hsep1 G.PackNatural 5
    --G.boxPackStart listsVBox schmAndClass G.PackNatural 2
    ---
    G.boxPackStart listsVBox hsep G.PackNatural 5
    mapM_ (\b -> G.boxPackStart buttsVBox b G.PackNatural 2) [analButton,previewButt ]
    mapM_ (\b -> G.boxPackEnd buttsVBox b G.PackNatural 4) [addButton,clrButt]
    -- put the options here
    G.boxPackStart listsVBox buttsVBox G.PackGrow 0
    --
    G.boxPackStart mainVBox topHBox G.PackNatural 6
    ------------- the bottom of the left pane -----------------------------------------.
    --- the left side has a frame highlighting the selected condition
    ---- the right the progress log
    -------- first get the table for the selected conditions. The handles for adding
    ---- this comes from the main display?
    [selectedConditions, progressLog] <- sequence $ replicate 2 G.frameNew
    G.set progressLog [G.frameLabel G.:= " Progress log" ]
    G.set selectedConditions [G.frameLabel G.:= " Selected conditions" ]
    G.containerAdd progressLog scrwin
    G.containerAdd selectedConditions selectedCondsTable
    -- tableWithWidgetList isVertical  widgets homo spacing
    displayLogs <- tableWithWidgetList False  [selectedConditions, progressLog] True 5
    G.boxPackStart  bottomHBox displayLogs G.PackGrow 6
    G.boxPackStart mainVBox bottomHBox  G.PackGrow 6
    -------------------------
    --G.widgetModifyBg mainVBox G.StateActive (G.Color 190 190 190)
    let rbutts = condTypes ++ scnSem
    -- check what has been extracted already
    --checkIfExtracted logProgress
    G.on previewButt G.buttonActivated $ do
        -- extract and align the file, bot do not analyse
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,False)
    --
    G.on analButton G.buttonActivated $ do
        --let btyp = (analButton,True)
        handleForAnalAndExtract extractAnal fileEntry detailsListRef dataTypeRef logProgress (analButton,True)
    ------------------------------------------------------------------------------------
    let pParms = PreviewParms logProgress yearsEntry distEntry negativeSlopes sl
    readIORef detailsListRef >>= \(sels,pms,_) -> do
        return (mainVBox, Nothing, rbutts, fileEntry,pParms)
    where
        getSelectedConditionsTable = do
            labels <- mapM (G.labelNew . Just) [" No."," Description "]
            headBox <- G.hBoxNew False 1
            displayBox <- G.vBoxNew False 1
            ---
            G.boxPackStart headBox (labels !! 0)  G.PackNatural 1
            G.boxPackEnd headBox (labels !! 1)  G.PackGrow 1
            G.vSeparatorNew >>= \sep -> G.boxPackEnd headBox sep  G.PackNatural 0
            ---
            (display, dispBuffer) <- makeScrolledEntryArea  HScroll False False
            G.boxPackStart displayBox headBox G.PackNatural 1
            G.boxPackStart displayBox display G.PackGrow 1
            return (displayBox , dispBuffer)
            --G.tableAttachDefaults entryTable (entryPairs !! 0) 0 1 0 1
        --
        validateFilePath str =
            let string = "The name entered is not a valid file path." in
                if isValid str then Nothing else (Just string)
        -- countRef
        write2Buffer tbuffer wrt string  = do
            let wrds = words string
            if not (null wrds) && head wrds == "Finished" then
                G.textBufferGetEndIter tbuffer >>= \iter ->
                    G.textBufferInsert tbuffer iter (string ++"\n")
            else
                wrt string
        -- handle for analayis and Extraction ---  extract, analyse, extNorAnl
        handleForAnalAndExtract extAnal fileEnt deatilsLstRef dataTypRef wrt butType = do
            extnl <- readIORef extAnal
            let (button,isAnal) = butType
            case extnl of
                Nothing -> do
                -- Just _  -
                    --let senstize = G.widgetSetSensitive button True
                    --let deSenstize = G.widgetSetSensitive button False
                    let reSetFlag = do
                                        modifyIORef  extAnal (\_ -> Nothing)
                                        check <- readIORef extAnal
                                        print (show check)
                    filePath <- G.entryGetText fileEnt
                    case validateFilePath filePath of
                        Just errString  ->
                            runMsgDialog Nothing errString Error
                        Nothing  -> do
                            -- forkIO $ copty file to the files folder. Useful for extracting HMDIF
                            --(sl,_,_) <- readIORef detailsListRef
                            (sels,pms,_) <- readIORef deatilsLstRef
                            if null sels then
                                runMsgDialog Nothing "You have not selected any parameter investigate" Error
                            else do
                                -- parse the file for scrim or scanner
                                fileOk <-  readIORef dataTypRef >>= parseFile filePath -- fKind
                                case fileOk of
                                    Nothing -> do
                                    ----
                                        let line chr = '\n' : replicate 40 chr ++"\n"
                                        let toAnalyse (sc, (ye,dst,ns)) = display sc ++ ": \n\t-\
                                            \ Maint. frequency: "++show ye++"\
                                            \ years; \n\t- Dist. between maint. works: "++ show dst ++ "\
                                            \ Km; \n\t- Negative slopes: "++ show ns ++ line '-'
                                        let list = concatMap toAnalyse $ zip sels pms
                                        let st = "You have choosen to Analyse the following:"++ line '='
                                        let qt   = line '=' ++ "\n\nDo you wish to proceed? "
                                        ----- need a decision dialog here with the stuff being done
                                        let labelInfo = "Running MML2DS on the selected conditions. "
                                        --- set up the progress buffer ------------------------
                                        let runAnalysis = do
                                            g <- newStdGen
                                            let anF dp ye dst ns dk n m = exF dp ye dst ns dk n m
                                            --let anF tds = mml2DsGD g tds
                                            -- mml2DsGD g dp ye dst ns dk n m wrt
                                            --let exF _ _ _ _ _ _ _   = return (([],[]) :: ([(OModel, ([Double], [Int]))], [Int]))
                                            let analFun = if isAnal then anF else exF
                                            runAnalysisFromWindow filePath wrt analFun $ zip sels pms -- >> reSetFlag
                                        wrt labelInfo -- show what process is being done
                                        modifyIORef  extAnal (\_ -> Just isAnal)
                                        forkProcess (Just labelInfo) wrt runAnalysis (Just reSetFlag)
                                        -- deSenstize
                                    Just errString ->  runMsgDialog Nothing errString Error
                Just ea -> do
                    -- show a message if analysis or extract is clicked when a process is already running
                    let exOrAn = if ea then  "analysis"  else "extraction"
                    let errString = "An "++exOrAn++ " process is currently running, which \
                                    \ muct be completed before you can proceed with this action."
                    runMsgDialog Nothing errString Error
            where
                        exF :: Int -> Double -> Double -> Bool -> Int
                                -> Int -> Int -> [[Double]]
                                -> IO [([(OModel, ([Double], [Int]))], [Int])]
                        exF  _ _ _ _ _ _ _ _ = return []
                        ---


-------------------------------------------------------------------------------------
-- test: running the analysis on all the data from the analyisis window
-------------------------------------------------------------------------------------
type Data = [[Double]]
runAnalysisFromWindow :: String ->
    (String -> IO ()) ->
    --(Double -> Double -> Bool -> Data -> IO ([([(OModel, ([Double], [Int]))], [Int])])) ->
    (   Int    -> -- search depth
            Double -> -- range in years
            Double -> -- range in distance
            --g      -> -- random starting value
            Bool   -> -- ignore negative slopes
            --Int    -> -- the maximum number of possible cuts for the segment. See QueryDialog for details
            Int    -> -- the maximum number of chains to align
            Int    -> -- the minimum number of chains to align
            Int    -> -- the minimum number of points to trend
            [[Double]] ->
            IO [([(OModel, ([Double], [Int]))], [Int]) ]) ->
    [(Defect,(Double,Double,Bool))] -> IO ()
runAnalysisFromWindow fileName write2B anlF options = do
     let runAnalysis (sc ,(yr, ds, ns)) = -- (anlF yr ds ns) -- (\a -> anlF a yr ds ns)
            bs2HMDIF2bs_aux Nothing fileName write2B   Nothing Rapid (show sc, scode2align sc) (5,35) Nothing
     mapM_ runAnalysis options
     return () -- force a return

------------------------------------------------------------------------------------}
--
------------------------------------------------------------------------------------