<commit_before>namespace IntelliFactory.WebSharper.D3

open IntelliFactory.WebSharper.InterfaceGenerator

module Definition =
    let mutable classList = [] : CodeModel.NamespaceEntity list

    let addToClassList c =
        classList <- upcast c :: classList

    let ( |>! ) x f =
        f x
        x

    let EnumStrings name words = Pattern.EnumStrings name words |>! addToClassList

    let DefineRecord name propList =
        Class name
        |+> Protocol (propList |> List.map (fun (n, t) -> upcast (n =@ t)))

    let Record name propList =
        DefineRecord name propList
        |>! addToClassList

    let O = T<unit>
    let String = T<string>
    let Int = T<int>
    let Float = T<float>
    let Obj = T<obj>
    let Bool = T<bool>
    let Error = T<exn>
    let ( !| ) x = Type.ArrayOf x

    let Int2T = Type.Tuple [Int; Int]
    let Int2x2T = Type.Tuple [Int2T; Int2T]
    let Float2T = Type.Tuple [Float; Float]
    let Float3T = Type.Tuple [Float; Float; Float]
    let Float2x2T = Type.Tuple [Float2T; Float2T]
    let Comparator = Obj * Obj ^-> Int

    let Date = T<IntelliFactory.WebSharper.EcmaScript.Date>
    let DateTime = T<System.DateTime>

    let Element = T<IntelliFactory.WebSharper.Dom.Element>
    let NodeList = T<IntelliFactory.WebSharper.Dom.NodeList>
    let Event = T<IntelliFactory.WebSharper.Dom.Event>

    let nameArg = String?name

    let WithThis t ps r = (t -* ps ^-> r) + (ps ^-> r)

    let selectionCallback ret = WithThis Element (Obj?d * Int?i) ret

    let getVal t = O ^-> t
    //let setVal chained (t: obj) = chained t?value
    let setValF t = (t + selectionCallback t)?value
    let getSetValF chained t = getVal t + chained (setValF t)
    let getSetVal chained (t: Type.IType) = getVal t + chained t

    let getProp t = nameArg ^-> t
    let setProp t = nameArg * t?value
    let setPropF t = nameArg * (t + selectionCallback t)?value
    let getSetPropF chained t = getProp t + chained (setPropF t)
    let getSetProp chained (t: Type.Type) = getProp t + chained (setProp t)

    let NameValuePair =
        Record "NameValuePair" [
            "name"  , String
            "value" , String
        ]

    let Transition = Type.New()

    let selector = (String + Element + selectionCallback !|Element + selectionCallback NodeList)?selector

    let ChainedClassG name (t: Type.Type) (members : ((Type.IParameters -> Type.Type) -> CodeModel.Member list)) =
        Class name |=> t |+> Protocol (members <| fun args -> args ^-> t)

    let ChainedClass name (t: Type.Type) (members : ((Type.IParameters -> Type.Type) -> CodeModel.Member list)) =
        Class name |=> t |+> Protocol (members <| fun args -> args ^-> t)
        |>! addToClassList

    let ChainedClassNew name members =
        ChainedClass name (Type.New()) members

    let ChainedClassNewInherits name inherits members =
        ChainedClassNew name members |=> Inherits inherits

    let ChainedClassInheritsG name t inherits members =
        ChainedClassG name t members |=> Inherits inherits

//    let Selection = Type.New()

//    let UpdateSelectionT =
//        Generic / fun t ->
//            Class "UpdateSelection"
//            |=> Inherits Selection
////            |+> Protocol
////                [
////                    "data" =>
////                        (
////                            let data = !|Obj + !|Float + !|Int + selectionCallback !|Obj
////                            let keyFunc = selectionCallback String
////                            data?values * !?keyFunc?key ^-> UpdateSelection
////                        )
////                    "data"       => O ^-> !|Obj
////                    "datum"      => chained (Obj + selectionCallback Obj)?value
////                    "filter"     => chained (String + selectionCallback Bool)?selector
////                    "sort"       => chained O
////                    "order"      => chained O
////                    "each"       => chained (selectionCallback O)
////                ]
//
//    addToClassList <| Generic - UpdateSelectionT

    let Selection =
        let selfG = Type.New()
        let attrValue = String + Float + Int + Obj
        Generic / fun (t: Type.Type) ->
            let self = selfG.[t]
            let chained x = x ^-> self
            let data : CodeModel.Member list = // .data(..)
                let elFunc x y = WithThis Element (x?datum * T<int>?index) y
                [
                    Generic - fun x -> "data" => (!|x)?data ^-> selfG.[x]
                    Generic - fun x y -> "data" => (elFunc x !|y)?proj ^-> selfG.[x]
                    Generic - fun x y -> "data" => (!|x)?data * (elFunc x y)?key ^-> selfG.[x]
                    "data" => O ^-> !|t
                ]
            Class "Selection"
            |=> selfG
            |+> Protocol
                [
                    // TODO: NameValuePair
                    "attr" => String ^-> Obj
                    "attr" => String * Obj ^-> self
                    "attr" => String * (WithThis Element t attrValue) ^-> self
                    |> WithSourceName "AttrFn" // disambiguating for better completion
                    ("attr" => String * (WithThis Element (t * Int) attrValue) ^-> self)
                    |> WithSourceName "AttrIx" // same as above
                    "classed"    => getSetPropF chained Bool
                    "style"      => getProp Obj + chained (setPropF Obj * !?String?priority)
                    "property"   => getSetPropF chained Obj
                    "text"       => getSetValF chained String
                    "html"       => getSetValF chained String
                    "append"     => chained nameArg
                    "insert"     => chained (nameArg * !?(String + selectionCallback Element)?before)
                    "remove"     => chained O

                    // TODO: datum, filter, sort, order, each - can make use of `t` parameter
                    "datum"      => chained (Obj + selectionCallback Obj)?value
                    "filter"     => chained (String + selectionCallback Bool)?selector
                    "sort"       => chained O<commit_msg>Comparator parameter for selection sort<commit_after>namespace IntelliFactory.WebSharper.D3

open IntelliFactory.WebSharper.InterfaceGenerator

module Definition =
    let mutable classList = [] : CodeModel.NamespaceEntity list

    let addToClassList c =
        classList <- upcast c :: classList

    let ( |>! ) x f =
        f x
        x

    let EnumStrings name words = Pattern.EnumStrings name words |>! addToClassList

    let DefineRecord name propList =
        Class name
        |+> Protocol (propList |> List.map (fun (n, t) -> upcast (n =@ t)))

    let Record name propList =
        DefineRecord name propList
        |>! addToClassList

    let O = T<unit>
    let String = T<string>
    let Int = T<int>
    let Float = T<float>
    let Obj = T<obj>
    let Bool = T<bool>
    let Error = T<exn>
    let ( !| ) x = Type.ArrayOf x

    let Int2T = Type.Tuple [Int; Int]
    let Int2x2T = Type.Tuple [Int2T; Int2T]
    let Float2T = Type.Tuple [Float; Float]
    let Float3T = Type.Tuple [Float; Float; Float]
    let Float2x2T = Type.Tuple [Float2T; Float2T]
    let Comparator = Obj * Obj ^-> Int

    let Date = T<IntelliFactory.WebSharper.EcmaScript.Date>
    let DateTime = T<System.DateTime>

    let Element = T<IntelliFactory.WebSharper.Dom.Element>
    let NodeList = T<IntelliFactory.WebSharper.Dom.NodeList>
    let Event = T<IntelliFactory.WebSharper.Dom.Event>

    let nameArg = String?name

    let WithThis t ps r = (t -* ps ^-> r) + (ps ^-> r)

    let selectionCallback ret = WithThis Element (Obj?d * Int?i) ret

    let getVal t = O ^-> t
    //let setVal chained (t: obj) = chained t?value
    let setValF t = (t + selectionCallback t)?value
    let getSetValF chained t = getVal t + chained (setValF t)
    let getSetVal chained (t: Type.IType) = getVal t + chained t

    let getProp t = nameArg ^-> t
    let setProp t = nameArg * t?value
    let setPropF t = nameArg * (t + selectionCallback t)?value
    let getSetPropF chained t = getProp t + chained (setPropF t)
    let getSetProp chained (t: Type.Type) = getProp t + chained (setProp t)

    let NameValuePair =
        Record "NameValuePair" [
            "name"  , String
            "value" , String
        ]

    let Transition = Type.New()

    let selector = (String + Element + selectionCallback !|Element + selectionCallback NodeList)?selector

    let ChainedClassG name (t: Type.Type) (members : ((Type.IParameters -> Type.Type) -> CodeModel.Member list)) =
        Class name |=> t |+> Protocol (members <| fun args -> args ^-> t)

    let ChainedClass name (t: Type.Type) (members : ((Type.IParameters -> Type.Type) -> CodeModel.Member list)) =
        Class name |=> t |+> Protocol (members <| fun args -> args ^-> t)
        |>! addToClassList

    let ChainedClassNew name members =
        ChainedClass name (Type.New()) members

    let ChainedClassNewInherits name inherits members =
        ChainedClassNew name members |=> Inherits inherits

    let ChainedClassInheritsG name t inherits members =
        ChainedClassG name t members |=> Inherits inherits

//    let Selection = Type.New()

//    let UpdateSelectionT =
//        Generic / fun t ->
//            Class "UpdateSelection"
//            |=> Inherits Selection
////            |+> Protocol
////                [
////                    "data" =>
////                        (
////                            let data = !|Obj + !|Float + !|Int + selectionCallback !|Obj
////                            let keyFunc = selectionCallback String
////                            data?values * !?keyFunc?key ^-> UpdateSelection
////                        )
////                    "data"       => O ^-> !|Obj
////                    "datum"      => chained (Obj + selectionCallback Obj)?value
////                    "filter"     => chained (String + selectionCallback Bool)?selector
////                    "sort"       => chained O
////                    "order"      => chained O
////                    "each"       => chained (selectionCallback O)
////                ]
//
//    addToClassList <| Generic - UpdateSelectionT

    let Selection =
        let selfG = Type.New()
        let attrValue = String + Float + Int + Obj
        Generic / fun (t: Type.Type) ->
            let self = selfG.[t]
            let chained x = x ^-> self
            let data : CodeModel.Member list = // .data(..)
                let elFunc x y = WithThis Element (x?datum * T<int>?index) y
                [
                    Generic - fun x -> "data" => (!|x)?data ^-> selfG.[x]
                    Generic - fun x y -> "data" => (elFunc x !|y)?proj ^-> selfG.[x]
                    Generic - fun x y -> "data" => (!|x)?data * (elFunc x y)?key ^-> selfG.[x]
                    "data" => O ^-> !|t
                ]
            Class "Selection"
            |=> selfG
            |+> Protocol
                [
                    // TODO: NameValuePair
                    "attr" => String ^-> Obj
                    "attr" => String * Obj ^-> self
                    "attr" => String * (WithThis Element t attrValue) ^-> self
                    |> WithSourceName "AttrFn" // disambiguating for better completion
                    ("attr" => String * (WithThis Element (t * Int) attrValue) ^-> self)
                    |> WithSourceName "AttrIx" // same as above
                    "classed"    => getSetPropF chained Bool
                    "style"      => getProp Obj + chained (setPropF Obj * !?String?priority)
                    "property"   => getSetPropF chained Obj
                    "text"       => getSetValF chained String
                    "html"       => getSetValF chained String
                    "append"     => chained nameArg
                    "insert"     => chained (nameArg * !?(String + selectionCallback Element)?before)
                    "remove"     => chained O

                    // TODO: datum, filter, sort, order, each - can make use of `t` parameter
                    "datum"      => chained (Obj + selectionCallback Obj)?value
                    "filter"     => chained (String + selectionCallback Bool)?selector
                    "sort"       => chained !?Comparator?comparator
{'fraction_non_alphanumeric': 0.1190784155214228, 'fraction_numerical': 0.0019401778496362166, 'mean_word_length': 1.654151469641708, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 177, 'https://': 0, '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': '1867039', 'n_tokens_mistral': 3632, 'n_tokens_neox': 3494, 'n_words': 1053}