<commit_before>module Files exposing
    ( Files
    , empty
    , new, delete
    , open, close
    , update, updateWithoutRecording
    , hasChanged
    , save, saveAs
    , undo, redo
    , get
    )

{-| A data structure for a flat list of files (without folders!), which can be opened, closed, saved, etc.. Each file keeps its own history and hence allows undo redo operations. An example usage can be seen in the source of [this app](https://erkal.github.io/kite/).

The main data structure, called `Files`, keeps an order of the files. The API allows the user to move files via `move` function.
Apart from this, it behaves similar to most editors, namely:

  - If a new file is added (via `new`), it gets immediately opened.
  - If a file is closed, the past and the future of the file gets lost, in the sense that undo and redo will not work directly after the file is reopened.
  - `close`, and `reallyClose` gives you the oportunity to ask the user if she really wants to close the file, in the case that there are unsaved changes.


# Definition

@docs Files


# Constructor

@docs empty


# Adding and Deleting Files

@docs new, delete


# Opening and closing Files

@docs open, close, closeAll


# Updating the opened file

@docs update, updateWithoutRecording


# Queries, to use in the view

@docs getPresent, hasChanged


# Saving

@docs save, saveAs, saveAll


# Undo-redo on the opened file

@docs undo, redo

-}

import Array exposing (Array)
import UndoList as UL exposing (UndoList)


{-| -}
type Files data
    = Files
        { maybeOpenedFile : Maybe FileIndex
        , arr : Array (File data)
        }


type alias File data =
    { name : String
    , uL : UndoList data
    , lastSave : data
    }


type alias FileIndex =
    Int


{-| an empty `Files`. This is the only constructor.
-}
empty : Files data
empty =
    Files
        { maybeOpenedFile = Nothing
        , arr = Array.empty
        }



--


get =
    42


hasChanged : FileIndex -> Files data -> Bool
hasChanged fileId (Files { arr }) =
    Array.get fileId arr
        |> Maybe.map (.uL >> UL.hasPast)
        |> Maybe.withDefault False



--


new : String -> data -> Files data -> Files data
new name d fL =
    -- TODO
    fL


delete : Files data -> Files data
delete (Files files) =
    Files files



--


{-| `open i` opens the file with the index **i** given that **i** is smaller than the number of files. If **i** is out of bounds, than it closes the opened file. This serves as a warning because, usually, the GUI should not allow this case to happen.
The indexing of files starts with 0.
-}
open : FileIndex -> Files data -> Files data
open i (Files files) =
    Files
        { files
            | maybeOpenedFile =
                if i < Array.length files.arr then
                    Just i

                else
                    Nothing
        }


close =
    42


reallyClose =
    42



--


update : (data -> data) -> Files data -> Files data
update up (Files files) =
    Files files


updateWithoutRecording : (data -> data) -> Files data -> Files data
updateWithoutRecording up (Files files) =
    Files files


undo : Files data -> Files data
undo fL =
    -- TODO
    fL


redo : Files data -> Files data
redo fL =
    -- TODO
    fL


save : Files data -> Files data
save fL =
    -- TODO
    fL


saveAs : String -> Files data -> Files data
saveAs name fL =
    -- TODO
    fL
<commit_msg>improved Files.elm<commit_after>module Files exposing
    ( Files
    , empty
    , new, delete
    , focus, close, reallyClose, closeAll
    , update, updateWithoutRecording
    , save, saveAs, saveAll
    , undo, redo
    , getPresent, hasChanged
    )

{-| Represent an ordered list of files, allowing undo-redo operations on each file. The files can be closed, saved, etc.. An example usage can be seen in the source of [this app](https://erkal.github.io/kite/).

The main data structure, called `Files`, keeps an **ordered** list of files and the API allows the user to move files via `move` function.
Apart from this, it behaves similar to most editors, namely:

  - If a new file is added (via `new`), it immediately becomes active.
  - If a file is closed, the past and the future of the file gets lost, in the sense that undo and redo will not work directly after the file is refocused.
  - `close`, and `reallyClose` gives you the oportunity to ask the user if she really wants to close the file, in the case that there are unsaved changes.

**Main restrictions:**

  - There is no folder structure.
  - There is no concept of "opening a file". Instead, use `hasChanged`.
  - There is no way of getting data of a file if the file is not focused.


# Definition

@docs Files


# Constructor

@docs empty


# Adding and Deleting Files

@docs new, delete


# Focusing and Closing Files

@docs focus, close, reallyClose, closeAll


# Updating Focused File

@docs update, updateWithoutRecording


# Saving

@docs save, saveAs, saveAll


# Undo-Redo on Focused File

@docs undo, redo


# Queries (only to use in **view**)

@docs getPresent, hasChanged

-}

import Array exposing (Array)
import UndoList as UL exposing (UndoList)


{-| -}
type Files data
    = Files
        { maybeOpenedFile : Maybe FileIndex
        , arr : Array (File data)
        }


type alias File data =
    { name : String
    , uL : UndoList data
    , lastSave : data
    }


type alias FileIndex =
    Int


{-| an empty `Files`. This is the only constructor.
-}
empty : Files data
empty =
    Files
        { maybeOpenedFile = Nothing
        , arr = Array.empty
        }



--


getPresent =
    42


hasChanged : FileIndex -> Files data -> Bool
hasChanged fileId (Files { arr }) =
    Array.get fileId arr
        |> Maybe.map (.uL >> UL.hasPast)
        |> Maybe.withDefault False



--


new : String -> data -> Files data -> Files data
new name d fL =
    -- TODO
    fL


delete : Files data -> Files data
delete (Files files) =
    Files files



--


{-| `focus i` focuses the file with index **i** given that **i** is smaller than the number of files. If **i** is out of bounds, than it makes the focus get lost. This serves as a warning because, usually, the GUI should not allow such a high value for `i`.
The indexing of files starts with 0.
-}
focus : FileIndex -> Files data -> Files data
focus i (Files files) =
    Files
        { files
            | maybeOpenedFile =
                if i < Array.length files.arr then
                    Just i

                else
                    Nothing
        }


close =
    42


closeAll =
    42


reallyClose =
    42



--


update : (data -> data) -> Files data -> Files data
update up (Files files) =
    Files files


updateWithoutRecording : (data -> data) -> Files data -> Files data
updateWithoutRecording up (Files files) =
    Files files


undo : Files data -> Files data
undo fL =
    -- TODO
    fL


redo : Files data -> Files data
redo fL =
    -- TODO
    fL


save : Files data -> Files data
save fL =
    -- TODO
    fL


saveAs : String -> Files data -> Files data
saveAs name fL =
    -- TODO
    fL


saveAll =
    42

{'fraction_non_alphanumeric': 0.08460022522522523, 'fraction_numerical': 0.002533783783783784, 'mean_word_length': 2.357750472589792, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 49, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2677891', 'n_tokens_mistral': 2207, 'n_tokens_neox': 2064, 'n_words': 935}