<commit_before>﻿open System.Xml
open System.Xml.Linq
open System.IO
open System.Collections.Generic
open System.Collections

let path, package =
    let args = System.Environment.GetCommandLineArgs()
    if args.Length <> 3 then
        failwith "Specify project folder and package as command line arguments"
    args.[1], args.[2]

let writeToFile fn (str : string) =
   let conv = System.Text.Encoding.UTF8
   use f = File.CreateText fn
   f.WriteLine str

let append (stringBuilder : System.Text.StringBuilder) (str : string) = stringBuilder.Append str |> ignore
let insert (stringBuilder : System.Text.StringBuilder) (str : string) = stringBuilder.Insert(0, str) |> ignore

let transitions = new Hashtable()

let transformXml = 
    System.IO.Directory.CreateDirectory(path + @"\res\layout") |> ignore
    let newXml = new System.Text.StringBuilder()
    let reader = XmlReader.Create(path + @"\forms.xml")
    let appendXml = append newXml
    let mutable currentDepth = 0
    let mutable hasAttr = false
    let mutable fileName = ""
    try
        while reader.Read() do
            let name = reader.Name
            match name with
            | "form" ->
                if reader.NodeType = XmlNodeType.EndElement then
                    writeToFile (path + @"\res\layout\" + fileName + ".xml") <| newXml.ToString()
                    newXml.Clear() |> ignore
                else
                    fileName <- reader.GetAttribute("form_name")
                    appendXml "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
            |  "" | "xml" | "forms" -> ()
            | _ -> 
                if name = "Button" then transitions.Add(reader.GetAttribute "id", reader.GetAttribute "onClick")
                let depth = reader.Depth

                if hasAttr then
                    if currentDepth < depth then " >\n"
                    elif (reader.NodeType = XmlNodeType.EndElement) && (currentDepth = depth) then " >\n"
                    else " />\n"
                    |> appendXml

                currentDepth <- depth

                let tab = "    "

                appendXml <| String.replicate (depth - 2) tab
                let amount = reader.AttributeCount

                match amount with
                | 0 -> hasAttr <- false
                | _ -> hasAttr <- true

                appendXml "\n"

                appendXml <|
                if not hasAttr then "</" + name + ">" + "\n"
                else "<" + name + "\n"

                for i in 0..amount - 1 do
                    appendXml <| String.replicate (depth - 1) tab
                    reader.MoveToAttribute i

                    match reader.Name with
                    | "xmlns" -> reader.Name + ":android"
                    | _ -> "android:" + reader.Name
                    |> fun pref -> appendXml <| pref + "=" + "\"" + reader.Value + "\""

                    if i <> amount - 1 then appendXml "\n"

        with | :? System.Xml.XmlException as e ->
            failwithf "Error while parsing %s: %s" path e.Message

    reader.Close()

// permissions register
let permissions = new Dictionary<_,_>()

let activities = new System.Text.StringBuilder()

let manifest = new System.Text.StringBuilder()
append manifest <| "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"
    package=\"com.qrealclouds." + package + "\"
    android:versionCode=\"1\"
    android:versionName=\"1.0\">

    <uses-sdk android:minSdkVersion=\"8\"/>\n"

let createImplementation form =
    if form = "main" then
        append activities <| "        <activity android:name=\".main\"
            android:label=\"Default\">
            <intent-filter>
                <action android:name=\"android.intent.action.MAIN\"/>
                <category android:name=\"android.intent.category.LAUNCHER\"/>
            </intent-filter>
        </activity>"
    else
        append activities <| "\n        <activity android:name=\"." + form + "\"></activity>"

    // imports register
    let imports = new Dictionary<_,_>()

    let currentImports = new System.Text.StringBuilder()
    append currentImports <| "\nimport android.app.Activity;
import android.os.Bundle;
import android.view.View;\n"

    let onCreate = new System.Text.StringBuilder()
    append onCreate <| "\n\n    /**
    * Called when the activity is first created.
    */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout." + form + ");"
            
    let activity = System.Text.StringBuilder()
    let appendAct = append activity
    let insertAct = insert activity
    appendAct <| currentImports.ToString()
    appendAct <| "\npublic class " + form + " extends Activity {"

    let reader = XmlReader.Create(path + @"\res\layout\" + form + ".xml")
    try
        while reader.Read() do 
            match reader.Name with
            | "Button" ->
                let onClickName = reader.GetAttribute "android:onClick"
                let id = reader.GetAttribute "android:id"
                appendAct <| "\n\n    public void " + onClickName + "(View v) {"

                if transitions.ContainsKey id then
                    if not <| imports.ContainsKey "android.content.Intent" then
                        insertAct "\nimport android.content.Intent;"
                        imports.Add ("android.content.Intent", "android.content.Intent")

                    let nextForm = transitions.Item id :?> string

                    appendAct <| "
                Intent intent = new Intent(this, " + nextForm + ".class);
                startActivity(intent);"

                appendAct "\n    }"

            | "WebView" ->
                if not <| permissions.ContainsKey "Internet" then
                    append manifest "    <uses-permission android:name=\"android.permission.INTERNET\" />\n"
                    permissions.Add ("Internet", "Internet")

                if not <| imports.ContainsKey "android.webkit.WebView" then
                    insertAct "\nimport android.webkit.WebView;"
                    imports.Add ("android.webkit.WebView", "android.webkit.WebView")

                append onCreate <| "\n        WebView webView = (WebView) findViewById(R.id.webViewInfo);
            webView.getSettings().setJavaScriptEnabled(true);
            webView.loadUrl(\"http://www.lanit-tercom.ru\");" // сайт зашит в код (было необходимо для теста)
            | _ -> ()
    with | :? System.Xml.XmlException as e ->
        failwithf "Error while parsing %s: %s" form e.Message
    append onCreate "\n    }"
    appendAct <| onCreate.ToString()

    appendAct "\n}"

    insertAct <| "package com.qrealclouds." + package + ";\n"

    activity.ToString()
    |> writeToFile (path + @"\src\com\qrealclouds\" + package + "\\" + form + ".java")

System.IO.Directory.CreateDirectory(path + @"\src\com\qrealclouds\" + package) |> ignore

transformXml

for file in (new DirectoryInfo(path + @"\res\layout")).GetFiles() do
    let currentName = file.Name
    let length = currentName.Length<commit_msg>added opportunity for include websites<commit_after>﻿open System.Xml
open System.Xml.Linq
open System.IO
open System.Collections.Generic
open System.Collections

let path, package =
    let args = System.Environment.GetCommandLineArgs()
    if args.Length <> 3 then
        failwith "Specify project folder and package as command line arguments"
    args.[1], args.[2]

let writeToFile fn (str : string) =
   let conv = System.Text.Encoding.UTF8
   use f = File.CreateText fn
   f.WriteLine str

let append (stringBuilder : System.Text.StringBuilder) (str : string) = stringBuilder.Append str |> ignore
let insert (stringBuilder : System.Text.StringBuilder) (str : string) = stringBuilder.Insert(0, str) |> ignore

let transitions = new Hashtable()
let webViews = new Hashtable()

let transformXml = 
    System.IO.Directory.CreateDirectory(path + @"\res\layout") |> ignore
    let newXml = new System.Text.StringBuilder()
    let reader = XmlReader.Create(path + @"\forms.xml")
    let appendXml = append newXml
    let mutable currentDepth = 0
    let mutable hasAttr = false
    let mutable fileName = ""
    try
        while reader.Read() do
            let name = reader.Name
            match name with
            | "form" ->
                if reader.NodeType = XmlNodeType.EndElement then
                    writeToFile (path + @"\res\layout\" + fileName + ".xml") <| newXml.ToString()
                    newXml.Clear() |> ignore
                else
                    fileName <- reader.GetAttribute("form_name")
                    appendXml "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
            |  "" | "xml" | "forms" -> ()
            | _ -> 
                if name = "Button" then transitions.Add(reader.GetAttribute "id", reader.GetAttribute "onClick")
                if name = "WebView" then webViews.Add(reader.GetAttribute "id", reader.GetAttribute "url")
                let depth = reader.Depth

                if hasAttr then
                    if currentDepth < depth then " >\n"
                    elif (reader.NodeType = XmlNodeType.EndElement) && (currentDepth = depth) then " >\n"
                    else " />\n"
                    |> appendXml

                currentDepth <- depth

                let tab = "    "

                appendXml <| String.replicate (depth - 2) tab
                let amount = reader.AttributeCount

                match amount with
                | 0 -> hasAttr <- false
                | _ -> hasAttr <- true

                appendXml "\n"

                appendXml <|
                if not hasAttr then "</" + name + ">" + "\n"
                else "<" + name + "\n"

                for i in 0..amount - 1 do
                    appendXml <| String.replicate (depth - 1) tab
                    reader.MoveToAttribute i

                    match reader.Name with
                    | "url" when name = "WebView" -> ()
                    | "xmlns" as currentName -> appendXml <| currentName + ":android" + "=" + "\"" + reader.Value + "\""
                    | _ as currentName -> appendXml <| "android:" + reader.Name + "=" + "\"" + reader.Value + "\""

                    if i <> amount - 1 then appendXml "\n"

        with | :? System.Xml.XmlException as e ->
            failwithf "Error while parsing %s: %s" path e.Message

    reader.Close()

// permissions register
let permissions = new Dictionary<_,_>()

let activities = new System.Text.StringBuilder()

let manifest = new System.Text.StringBuilder()
append manifest <| "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"
    package=\"com.qrealclouds." + package + "\"
    android:versionCode=\"1\"
    android:versionName=\"1.0\">

    <uses-sdk android:minSdkVersion=\"8\"/>\n"

let createImplementation form =
    if form = "main" then
        append activities <| "        <activity android:name=\".main\"
            android:label=\"Default\">
            <intent-filter>
                <action android:name=\"android.intent.action.MAIN\"/>
                <category android:name=\"android.intent.category.LAUNCHER\"/>
            </intent-filter>
        </activity>"
    else
        append activities <| "\n        <activity android:name=\"." + form + "\"></activity>"

    // imports register
    let imports = new Dictionary<_,_>()

    let currentImports = new System.Text.StringBuilder()
    append currentImports <| "\nimport android.app.Activity;
import android.os.Bundle;
import android.view.View;\n"

    let onCreate = new System.Text.StringBuilder()
    append onCreate <| "\n\n    /**
    * Called when the activity is first created.
    */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout." + form + ");"
            
    let activity = System.Text.StringBuilder()
    let appendAct = append activity
    let insertAct = insert activity
    appendAct <| currentImports.ToString()
    appendAct <| "\npublic class " + form + " extends Activity {"

    let reader = XmlReader.Create(path + @"\res\layout\" + form + ".xml")
    try
        while reader.Read() do 
            match reader.Name with
            | "Button" ->
                let onClickName = reader.GetAttribute "android:onClick"
                let id = reader.GetAttribute "android:id"
                appendAct <| "\n\n    public void " + onClickName + "(View v) {"

                if transitions.ContainsKey id then
                    if not <| imports.ContainsKey "android.content.Intent" then
                        insertAct "\nimport android.content.Intent;"
                        imports.Add ("android.content.Intent", "android.content.Intent")

                    let nextForm = transitions.Item id :?> string

                    appendAct <| "
                Intent intent = new Intent(this, " + nextForm + ".class);
                startActivity(intent);"

                appendAct "\n    }"

            | "WebView" ->
                if not <| permissions.ContainsKey "Internet" then
                    append manifest "    <uses-permission android:name=\"android.permission.INTERNET\" />\n"
                    permissions.Add ("Internet", "Internet")

                if not <| imports.ContainsKey "android.webkit.WebView" then
                    insertAct "\nimport android.webkit.WebView;"
                    imports.Add ("android.webkit.WebView", "android.webkit.WebView")

                let id = reader.GetAttribute "android:id"
                let url = webViews.Item id :?> string

                append onCreate <| "\n        WebView webView = (WebView) findViewById(R.id." + id.Substring(5, id.Length - 5) + ");
            webView.getSettings().setJavaScriptEnabled(true);
            webView.loadUrl(\"" + url + "\");"
            | _ -> ()
    with | :? System.Xml.XmlException as e ->
        failwithf "Error while parsing %s: %s" form e.Message
    append onCreate "\n    }"
    appendAct <| onCreate.ToString()

    appendAct "\n}"

    insertAct <| "package com.qrealclouds." + package + ";\n"

    activity.ToString()
    |> writeToFile (path + @"\src\com\qrealclouds\" + package + "\\" + form + ".java")

System.IO.Directory.CreateDirectory(path + @"\src\com\qrealclouds\" + package) |> ignore

transformXml

for file in (new DirectoryInfo(path + @"\res\layout")).GetFiles() do
    let currentName = file.Name
    let length = currentName.Length
{'fraction_non_alphanumeric': 0.126143969403087, 'fraction_numerical': 0.0031416473159404453, 'mean_word_length': 1.9076648133439238, 'pattern_counts': {'":': 2, '<': 92, '<?xml version=': 4, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 16}, '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': '5820976', 'n_tokens_mistral': 4092, 'n_tokens_neox': 3842, 'n_words': 1023}