# MIT License

# Copyright (c) 2021 Rucknium

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


# install.packages("animation")
# install.packages("plotrix")
# install.packages("Cairo")
# NOTE: Cairo is a general software package that cannot be installed by R alone.
# Search for installation instructions according to your operating system.

library(animation)
library(plotrix)
library(Cairo)

load("logo-data.Rdata", verbose = TRUE)
# max(M.outline$y) == 1.58044863212111
# xmr.orange == "#FF6600FF"
# xmr.grey == "#4C4C4CFF"

load("generated-logo-observations.Rdata", verbose = TRUE)
# generated.logo.observations

# If Cairo in installed, use:
# ani.options(interval = 0.2, ani.dev = "CairoPNG")
# Otherwise, use:
ani.options(interval = 0.2)

saveGIF({
  
  y <- generated.logo.observations[1:10]

  for ( i in 3:73) {
    
    y <- c(y, generated.logo.observations[length(y) + (1:floor(2^(i/3-1))) ] )
    
    par(mar = c(5, 0, 0, 0))
    
    plot(0, 0, xlim = c(0 - 0.1, 1 + 0.1), ylim = c(0 , max(M.outline$y) * 2 ),
      axes = FALSE,
      ylab = "", xlab = "", main = "", col = "transparent",
      asp = (1.2)/(max(M.outline$y) * 2))
    
    mtext("Secure. Private. Untraceable.", side = 1, line = 0.5, cex = 2)
    mtext("Resistant to statistical attack.", side = 1, line = 2.5, cex = 2)
    mtext(paste0("N = ", prettyNum(length(y), big.mark = ",")), side = 1, line = 3.9, cex = 1)
    
    center_x = mean(c(0, 1))
    center_y = max(M.outline$y)
    
    plotrix::draw.ellipse(center_x, center_y,
      0.6, max(M.outline$y), 
      col = xmr.orange, border = NA)
    
    M.density <- density(y, bw = "SJ-dpi")
    
    polygon((c(M.density$x, M.density$x) * 1.5 - .5/2), 
      c(M.density$y, M.density$y * 1.5), border = NA, col = "white")
    
    hist(y, breaks = 50, col = xmr.grey, 
      axes = FALSE, border = NA,
      xlim = c(0, 1), ylim = c(0, max(M.outline$y) * 2),
      freq = FALSE,
      ylab = "", xlab = "", main = "", add = TRUE)
    
    
    # Pieced together from source of plotrix::draw.ellipse
    draw1ellipse <- function(x, y, a = 1, b = 1, angle = 0, segment = NULL, 
      arc.only = TRUE, nv = 100, deg = TRUE, border = NULL, 
      col = NA, lty = 1, lwd = 1, ...) {
      if (is.null(segment)) {
        if (deg) 
          segment <- c(0, 360)
        else segment <- c(0, 2 * pi)
      }
      if (deg) {
        angle <- angle * pi/180
        segment <- segment * pi/180
      }
      xyangle <- function(x, y, directed = FALSE, deg = TRUE) {
        if (missing(y)) {
          y <- x[, 2]
          x <- x[, 1]
        }
        out <- atan2(y, x)
        if (!directed) 
          out <- out%%pi
        if (deg) 
          out <- out * 180/pi
        out
      }
      z <- seq(segment[1], segment[2], length = nv + 1)
      xx <- a * cos(z)
      yy <- b * sin(z)
      alpha <- xyangle(xx, yy, directed = TRUE, deg = FALSE)
      rad <- sqrt(xx^2 + yy^2)
      xp <- rad * cos(alpha + angle) + x
      yp <- rad * sin(alpha + angle) + y
      if (!arc.only) {
        xp <- c(x, xp, x)
        yp <- c(y, yp, y)
      }
      data.frame(x = xp, y = yp)
    }
    
    
    eclipse <- draw1ellipse(center_x, center_y, 
      0.6, max(M.outline$y),
      segment = c(0, 180), angle = 180)
    
    eclipse <- rbind(data.frame(x = min(eclipse$x), y = -0.05),
      eclipse,
      data.frame(x = max(eclipse$x), y = 0))
    
    polygon(eclipse, col = "white", border = NA)
    
    print(paste(i, length(y)))
    
  }
  
}, movie.name = "Statistical-Monero-Logo.gif")