#!/bin/dunesh
#              _                                 
#     /\      | |                                
#    /  \   __| | __ _ _ __ ___                  
#   / /\ \ / _` |/ _` | '_ ` _ \                 
#  / ____ \ (_| | (_| | | | | | |                
# /_/  __\_\__,_|\__,_|_| |_| |_| _      _ _     
# |  \/  |    |  __ \            (_)    | ( )    
# | \  / | ___| |  | | __ _ _ __  _  ___| |/ ___ 
# | |\/| |/ __| |  | |/ _` | '_ \| |/ _ \ | / __|
# | |  | | (__| |__| | (_| | | | | |  __/ | \__ \
# |_|__|_|\___|_____/ \__,_|_|_|_|_|\___|_| |___/
# |  __ \        | |         | |                 
# | |__) | __ ___| |_   _  __| | ___             
# |  ___/ '__/ _ \ | | | |/ _` |/ _ \            
# | |   | | |  __/ | |_| | (_| |  __/            
# |_|   |_|  \___|_|\__,_|\__,_|\___|            
#
# Overview:
#   Splash screen:
#     welcome  # Prints splash screen
#     about    # Prints info about the shell
#     donate   # Prints donation message
#
#   Calendar widget:
#     cal      # Print a calendar
#
#   Shrew:
#     shrewsay "Message to print"        # Makes a wild dune shrew appear!
#     turnedshrewsay "Message to print"  # Makes a left-facing wild dune shrew appear!
#
# Have fun, scripters!


if os@name == "windows" {
    let ls = dir ~> fs@ls dir | join "\n" | echo;
    let rm = fs@rm;
    let cp = fs@cp;
    let mv = fs@mv;
    let mkdir = fs@mkdir;
    let rmdir = fs@rmdir;

    let cat = fs@read;
}

console@title "Dune";

let donate = _ ~> {
        echo "                     ┌──────Wild Dune Shrew──────┐
                      Hello, how is Dune working
                      for you so far? If you like
                      it, consider starring our
                      GitHub page and donating!";
        echo "                     " (fmt@italics "(To remove this message,\n                      write your own prelude)\n");
        echo "                     " (fmt@href "https://github.com/adam-mcdaniel/dune" "Thank You❤️");

        echo "                     └───────────────────────────┘
                     ╱
                    ╱

          _,____ c--.
        /`  \\   ` _^_\\
    `~~~\\  _/---'\\\\  ^
         `~~~     ~~
    ─────────────────────
"
};

let CATS = ["
     _
   |\\'/-..--.
  / _ _   ,  ;
 `~=`Y'~_<._./
  <`-....__.'",
"

 |\\__/,|   (`\\
 |_ _  |.--.) )
 ( T   )     /
(((^_(((/(((_/",
"

    \\    /\\
     )  ( ')
    (  /  )
     \\(__)|",
"

      ^~^  ,
     ('Y') )
     /   \\/
    (\\|||/)",
"   .       .
   \\`-\"'\"-'/
    } 6 6 {
   =.  Y  ,=
     /^^^\\  .
    /     \\  )
   (  )-(  )/
    \"\"   \"\"",
"

         /\\_/\\
    ____/ o o \\
  /~____  =Y= /
 (______)__m_m)"
];

let prompt = cwd -> fmt@bold ((fmt@dark@blue "(dune) ") + (fmt@bold (fmt@dark@green cwd)) + (fmt@bold (fmt@dark@blue "$ ")));
let incomplete_prompt = cwd -> ((len cwd) + (len "(dune) ")) * " " + (fmt@bold (fmt@dark@yellow "> "));

let shrew = _ ~> {
"
          _,____ c--.
        /`  \\   ` _^_\\
    `~~~\\  _/---'\\\\  ^
         `~~~     ~~
    ─────────────────────
"
};

let turnedshrew = _ ~> {
"
      .--p_____,_
     /_^_ `   /  `\\
     ^  //'---\\_  /~~~
       ~~     ~~~`
     ──────────────────
"
};

let shrewsay = text -> {
    let title = "Wild Dune Shrew";


    let cols = 22;
    let text = fmt@wrap text cols;
    let text-lines = lines text;
    if (len text-lines) == 1 {
        if (len text) < cols {
            let cols = len text;
        }
    }
    let rows = len text-lines;
    let spacing = 25;

    for line in (lines (widget@create title text cols + 2 rows + 2)) {
        echo " " * spacing line;
    }

    for i in 0 to 2 {
        echo " " * (spacing - i) "╱";
    }

    echo (shrew ());
};

let turnedshrewsay = text -> {
    let title = "Wild Dune Shrew";

    let cols = 27;
    let text = fmt@wrap text cols;
    let text-lines = lines text;
    if (len text-lines) == 1 {
        if (len text) < cols {
            let cols = len text;
        }
    }
    let rows = len text-lines;
    let spacing = 20;

    for line in (lines (widget@create title text cols + 2 rows + 2)) {
        echo " " * spacing line;
    }

    for i in 0 to 2 {
        echo " " * (spacing - i) "╱";
    }

    echo (turnedshrew ());
};


let about = _ ~> {
    echo (
    widget@joiny
        (widget@create "About"
"          Hello, welcome to " + (fmt@yellow "Dune Shell!") + "
      Written by: http://adam-mcdaniel.net\n\nI wrote Dune to be a nice environment for devs while they work! It's a very cozy shell with high customizability, so you can make it how you'd like." 50 10)

            (widget@joinx
            (widget@create "Features"
"Dune has a wide set of
features, it's basically a
full blown language!

It supports several uncommon
features in a shell, such as:
operator overloading,
lambdas, macros, quoted
expressions like Lisp, and
more!

Dune's libraries are very
extensive. There are
libraries for:

☞ A simple widget system🪟
☞ OS information        💽
☞ Randomness            🔀
☞ Basic math, trig, etc.🧮
☞ File system operations📂
☞ Text color and styling📝
☞ Functional programming🔗
☞ Date and time         🕒

And more!"
    30 28)

            (widget@joiny
                (widget@create "About the Author" "I'm a sophomore at\nthe University of\nTennessee🏴󠁵󠁳󠁴󠁮󠁿\nstudying Computer💻\nScience🧪.\n\nI'm extremely \ninterested in\nlanguage design\n& compiler design.\nCheck out my other\nprojects on GitHub:\n\nadam-mcdaniel" 20 18)
                (widget@create "Cat" (rand@choose CATS) 20 10)
    )))
};

let welcomebanner = _ ~> {


    let logo = "
        ██████╗ ██╗   ██╗███╗   ██╗███████╗
        ██╔══██╗██║   ██║████╗  ██║██╔════╝
        ██║  ██║██║   ██║██╔██╗ ██║█████╗
        ██║  ██║██║   ██║██║╚██╗██║██╔══╝
        ██████╔╝╚██████╔╝██║ ╚████║███████╗
        ╚═════╝  ╚═════╝ ╚═╝  ╚═══╝╚══════╝
                                     ";

    let logo = "

        ██████╗░██╗░░░██╗███╗░░██╗███████╗
        ██╔══██╗██║░░░██║████╗░██║██╔════╝
        ██║░░██║██║░░░██║██╔██╗██║█████╗░░
        ██║░░██║██║░░░██║██║╚████║██╔══╝░░
        ██████╔╝╚██████╔╝██║░╚███║███████╗
        ╚═════╝░░╚═════╝░╚═╝░░╚══╝╚══════╝
";

    (_ -> {
        let now = time@now ();
        let time-emoji = if now@hour <= 6 "🌃"
            else if now@hour <= 10 "🌅"
            else if now@hour <= 18 "🌤️ "
            else "🌃";
        let date-emoji = if now@month == 1 "⛄"
            else if now@month == 2 "💖"
            else if now@month == 3 "🍀"
            else if now@month == 4 "🌂"
            else if now@month == 5 "🌻"
            else if now@month == 6 "🌞"
            else if now@month == 7 "🌊"
            else if now@month == 8 "📝"
            else if now@month == 9 "🍎"
            else if now@month == 10 "🎃"
            else if now@month == 11 "🍂"
            else if now@month == 12 "🌨️"
            else "📅";
        let zodiac-emoji = if now@month == 1 (if now@day < 20 "🐐" else "🏺")
            else if now@month == 2 (if now@day < 19 "🏺" else "🐟")
            else if now@month == 3 (if now@day < 21 "🐟" else "🐏")
            else if now@month == 4 (if now@day < 20 "🐏" else "🐂")
            else if now@month == 5 (if now@day < 21 "🐂" else "👬")
            else if now@month == 6 (if now@day < 21 "👬" else "🦀")
            else if now@month == 7 (if now@day < 23 "🦀" else "🦁")
            else if now@month == 8 (if now@day < 23 "🦁" else "👩")
            else if now@month == 9 (if now@day < 23 "👩" else "⚖️")
            else if now@month == 10 (if now@day < 23 "⚖️" else "🦂")
            else if now@month == 11 (if now@day < 22 "🦂" else "🏹")
            else if now@month == 12 (if now@day < 22 "🏹" else "🐐")
            else "⭐";
        echo "┌─────────────────Welcome to ...─────────────────┐";
        for ch in (chars logo) {
            print (fmt@bold (if ch == "█" {
               fmt@faint (fmt@red ch)
            } else {
               fmt@faint (fmt@dark@blue ch)
            }));
        }
        echo "";
        echo "        The time is " + (fmt@magenta now@time@str) + " " + time-emoji + " on " + (fmt@cyan now@date@str);
        echo "└────────────────────────────────────────────────┘";
    }) ();

};


let is-leapyear = year -> {
    if year % 4 == 0 && year % 100 != 0 {
        True
    } else if year % 100 == 0 && year % 400 == 0 {
        True
    } else {
        False
    }
};

let days-in-month = month -> year -> {
    if month == 2 {
        28 + (if (is-leapyear year) 1 else 0)
    } else {
        31 - (((month - 1) % 7) % 2)
    }
};

let day-of-week = m -> d -> y -> {
    let t = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4];

    if m < 3 {
        let y = y - 1
    }

    (((y + (int(y // 4.0))) - (int(y // 100.0))) + (int(y // 400.0)) + t@(m - 1) + d) % 7
};

let WEEKDAYS = [
	"Sunday",
	"Monday",
	"Tuesday",
	"Wednesday",
	"Thursday",
	"Friday",
	"Saturday"
];

let MONTHS = [
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December"
];

let make-calendar = m -> d -> y -> {
    let now = {month=m, day=d, year=y};
    let result = MONTHS@(now@month - 1) + " " + (str now@day) + ", " + (str now@year) + "\n";
	let result = " " * ((28 - (len result)) // 2 + 1) + result;
    let result = result + " Su  Mo  Tu  We  Th  Fr  Sa\n";

    let dof = day-of-week now@month 1 now@year;
    let dim = days-in-month now@month now@year;

    for i in 0 to dof {
        let result = result + "    ";
    }

    for i in 1 to dim + 1 {
        let num = str i;
        if (len num) < 2 {
            let num = (if now@day == i " *" else "  ") + num
        } else {
            let num = (if now@day == i "*" else " ") + num
        }

        let result = result + num + (if (i + dof) % 7 == 0 "\n" else " ")
    }
    widget@create "Calendar" result 30 10
};

let cal = _ ~> {
    (_ -> {
        let now = time@now ();
        make-calendar now@month now@day now@year
    }) ();
};



let welcome = _ ~> {
    welcomebanner ();
    (_ -> {
        let now = time@now ();
        echo (widget@joinx
            (make-calendar now@month now@day now@year)
            (widget@create "Cat" (rand@choose CATS) 20 10));
    }) ();
};

clear ();
welcome ();
