#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

API = 2

Number.prototype.pad = (n) ->
  str = String(this)

  # Do we need to pad? if so, do it using String.repeat
  if (str.length < n)
      str = "0".repeat(n - str.length) + str;  
  return str


Number.prototype.pretty = (fix) ->
    if (fix)
        return String(this.toFixed(fix)).replace(/(\d)(?=(\d{3})+\.)/g, '$1,');
    return String(this.toFixed(0)).replace(/(\d)(?=(\d{3})+$)/g, '$1,');


fetch = (url, xstate, callback, nocreds) ->
    xmlHttp = null;
    # Set up request object
    if window.XMLHttpRequest
        xmlHttp = new XMLHttpRequest();
    else
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if not nocreds
        xmlHttp.withCredentials = true
    # GET URL
    xmlHttp.open("GET", "api/#{url}", true);
    xmlHttp.send(null);
    
    xmlHttp.onreadystatechange = (state) ->
            if xmlHttp.readyState == 4 and xmlHttp.status == 500
                if snap
                    snap(xstate)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status >= 400
                js = JSON.parse(xmlHttp.responseText)
                # If we need to log in first, redirect to login page
                if js.code == 403
                    mpart = location.href.match(/\/\/[^/]+\/(.+)$/)[1]
                    location.href = "login.html?redirect=" + mpart
                badModal(js.reason)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status == 200
                if callback
                    # Try to parse as JSON and deal with cache objects, fall back to old style parse-and-pass
                    try
                        response = JSON.parse(xmlHttp.responseText)
                        callback(response, xstate);
                    catch e
                        callback(JSON.parse(xmlHttp.responseText), xstate)

put = (url, json, xstate, callback, nocreds = false) ->
    xmlHttp = null;
    # Set up request object
    if window.XMLHttpRequest
        xmlHttp = new XMLHttpRequest();
    else
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if not nocreds
        xmlHttp.withCredentials = true
    # GET URL
    xmlHttp.open("PUT", "api/#{url}", true);
    xmlHttp.send(JSON.stringify(json || {}));
    
    xmlHttp.onreadystatechange = (state) ->
            if xmlHttp.readyState == 4 and xmlHttp.status == 500
                if snap
                    snap(xstate)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status >= 400
                js = JSON.parse(xmlHttp.responseText)
                badModal(js.reason)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status == 200
                if callback
                    # Try to parse as JSON and deal with cache objects, fall back to old style parse-and-pass
                    try
                        response = JSON.parse(xmlHttp.responseText)
                        if response && response.loginRequired
                            location.href = "/login.html"
                            return
                        callback(response, xstate);
                    catch e
                        callback(JSON.parse(xmlHttp.responseText), xstate)


patch = (url, json, xstate, callback, nocreds = false) ->
    xmlHttp = null;
    # Set up request object
    if window.XMLHttpRequest
        xmlHttp = new XMLHttpRequest();
    else
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if not nocreds
        xmlHttp.withCredentials = true
    # GET URL
    xmlHttp.open("PATCH", "api/#{url}", true);
    xmlHttp.send(JSON.stringify(json || {}));
    
    xmlHttp.onreadystatechange = (state) ->
            if xmlHttp.readyState == 4 and xmlHttp.status == 500
                if snap
                    snap(xstate)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status >= 400
                js = JSON.parse(xmlHttp.responseText)
                badModal(js.reason)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status == 200
                if callback
                    # Try to parse as JSON and deal with cache objects, fall back to old style parse-and-pass
                    try
                        response = JSON.parse(xmlHttp.responseText)
                        if response && response.loginRequired
                            location.href = "/login.html"
                            return
                        callback(response, xstate);
                    catch e
                        callback(JSON.parse(xmlHttp.responseText), xstate)

xdelete = (url, json, xstate, callback, nocreds = false) ->
    xmlHttp = null;
    # Set up request object
    if window.XMLHttpRequest
        xmlHttp = new XMLHttpRequest();
    else
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    if not nocreds
        xmlHttp.withCredentials = true
    # GET URL
    xmlHttp.open("DELETE", "api/#{url}", true);
    xmlHttp.send(JSON.stringify(json || {}));
    
    xmlHttp.onreadystatechange = (state) ->
            if xmlHttp.readyState == 4 and xmlHttp.status == 500
                if snap
                    snap(xstate)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status >= 400
                js = JSON.parse(xmlHttp.responseText)
                badModal(js.reason)
                return
            if xmlHttp.readyState == 4 and xmlHttp.status == 200
                if callback
                    # Try to parse as JSON and deal with cache objects, fall back to old style parse-and-pass
                    try
                        response = JSON.parse(xmlHttp.responseText)
                        if response && response.loginRequired
                            location.href = "/login.html"
                            return
                        callback(response, xstate);
                    catch e
                        callback(JSON.parse(xmlHttp.responseText), xstate)


post = (url, json, xstate, callback, snap) ->
    xmlHttp = null;
    # Set up request object
    if window.XMLHttpRequest
        xmlHttp = new XMLHttpRequest();
    else
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    xmlHttp.withCredentials = true
    # Construct form data
    for key, val of json
        if val.match
            if val.match(/^\d+$/)
                json[key] = parseInt(val)
            if val == 'true'
                json[key] = true
            if val == 'false'
                json[key] = false
    fdata = JSON.stringify(json)
    
    # POST URL
    xmlHttp.open("POST", "api/#{url}", true);
    xmlHttp.setRequestHeader("Content-type", "application/json");
    xmlHttp.send(fdata);
    
    xmlHttp.onreadystatechange = (state) ->
            if xmlHttp.readyState == 4 and xmlHttp.status == 500
                if snap
                    snap(xstate)
            if xmlHttp.readyState == 4 and xmlHttp.status == 200
                if callback
                    # Try to parse as JSON and deal with cache objects, fall back to old style parse-and-pass
                    try
                        response = JSON.parse(xmlHttp.responseText)
                        if xstate and xstate.widget
                                    xstate.widget.json = response
                        callback(response, xstate);
                    catch e
                        callback(JSON.parse(xmlHttp.responseText), xstate)

mk = (t, s, tt) ->
    r = document.createElement(t)
    if s
        for k, v of s
            if v
                r.setAttribute(k, v)
    if tt
        if typeof tt == "string"
            app(r, txt(tt))
        else
            if isArray tt
                for k in tt
                    if typeof k == "string"
                        app(r, txt(k))
                    else
                        app(r, k)
            else
                app(r, tt)
    return r

app = (a,b) ->
    if isArray b
        for item in b
            if typeof item == "string"
                item = txt(item)
            a.appendChild(item)
    else
        return a.appendChild(b)


set = (a, b, c) ->
    return a.setAttribute(b,c)

txt = (a) ->
    return document.createTextNode(a)

get = (a) ->
    return document.getElementById(a)

swi = (obj) ->
    switchery = new Switchery(obj, {
                color: '#26B99A'
            })

cog = (div, size = 200) ->
        idiv = document.createElement('div')
        idiv.setAttribute("class", "icon")
        idiv.setAttribute("style", "text-align: center; vertical-align: middle; height: 500px;")
        i = document.createElement('i')
        i.setAttribute("class", "fa fa-spin fa-cog")
        i.setAttribute("style", "font-size: " + size + "pt !important; color: #AAB;")
        idiv.appendChild(i)
        idiv.appendChild(document.createElement('br'))
        idiv.appendChild(document.createTextNode('Loading, hang on tight..!'))
        div.innerHTML = ""
        div.appendChild(idiv)

globArgs = {}


theme = {
          color: [],

          title: {
              itemGap: 8,
              textStyle: {
                  fontWeight: 'normal',
                  color: '#408829'
              }
          },

          dataRange: {
              color: ['#1f610a', '#97b58d']
          },

          toolbox: {
              color: ['#408829', '#408829', '#408829', '#408829']
          },

          tooltip: {
              backgroundColor: 'rgba(0,0,0,0.5)',
              axisPointer: {
                  type: 'line',
                  lineStyle: {
                      color: '#408829',
                      type: 'dashed'
                  },
                  crossStyle: {
                      color: '#408829'
                  },
                  shadowStyle: {
                      color: 'rgba(200,200,200,0.3)'
                  }
              }
          },

          dataZoom: {
              dataBackgroundColor: '#eee',
              fillerColor: 'rgba(64,136,41,0.2)',
              handleColor: '#408829'
          },
          grid: {
              borderWidth: 0
          },

          categoryAxis: {
              axisLine: {
                  lineStyle: {
                      color: '#408829'
                  }
              },
              splitLine: {
                  lineStyle: {
                      color: ['#eee']
                  }
              }
          },

          valueAxis: {
              axisLine: {
                  lineStyle: {
                      color: '#408829'
                  }
              },
              splitArea: {
                  show: true,
                  areaStyle: {
                      color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)']
                  }
              },
              splitLine: {
                  lineStyle: {
                      color: ['#eee']
                  }
              }
          },
          timeline: {
              lineStyle: {
                  color: '#408829'
              },
              controlStyle: {
                  normal: {color: '#408829'},
                  emphasis: {color: '#408829'}
              }
          },

          k: {
              itemStyle: {
                  normal: {
                      color: '#68a54a',
                      color0: '#a9cba2',
                      lineStyle: {
                          width: 1,
                          color: '#408829',
                          color0: '#86b379'
                      }
                  }
              }
          },
          map: {
              itemStyle: {
                  normal: {
                      areaStyle: {
                          color: '#ddd'
                      },
                      label: {
                          textStyle: {
                              color: '#c12e34'
                          }
                      }
                  },
                  emphasis: {
                      areaStyle: {
                          color: '#99d2dd'
                      },
                      label: {
                          textStyle: {
                              color: '#c12e34'
                          }
                      }
                  }
              }
          },
          force: {
              itemStyle: {
                  normal: {
                      linkStyle: {
                          strokeColor: '#408829'
                      }
                  }
              }
          },
          chord: {
              padding: 4,
              itemStyle: {
                  normal: {
                      lineStyle: {
                          width: 1,
                          color: 'rgba(128, 128, 128, 0.5)'
                      },
                      chordStyle: {
                          lineStyle: {
                              width: 1,
                              color: 'rgba(128, 128, 128, 0.5)'
                          }
                      }
                  },
                  emphasis: {
                      lineStyle: {
                          width: 1,
                          color: 'rgba(128, 128, 128, 0.5)'
                      },
                      chordStyle: {
                          lineStyle: {
                              width: 1,
                              color: 'rgba(128, 128, 128, 0.5)'
                          }
                      }
                  }
              }
          },
          gauge: {
              startAngle: 225,
              endAngle: -45,
              axisLine: {
                  show: true,
                  lineStyle: {
                      color: [[0.2, '#86b379'], [0.8, '#68a54a'], [1, '#408829']],
                      width: 8
                  }
              },
              axisTick: {
                  splitNumber: 10,
                  length: 12,
                  lineStyle: {
                      color: 'auto'
                  }
              },
              axisLabel: {
                  textStyle: {
                      color: 'auto'
                  }
              },
              splitLine: {
                  length: 18,
                  lineStyle: {
                      color: 'auto'
                  }
              },
              pointer: {
                  length: '90%',
                  color: 'auto'
              },
              title: {
                  textStyle: {
                      color: '#333'
                  }
              },
              detail: {
                  textStyle: {
                      color: 'auto'
                  }
              }
          },
          textStyle: {
              fontFamily: 'Arial, Verdana, sans-serif'
          }
      };

isArray = ( value ) ->
    value and
        typeof value is 'object' and
        value instanceof Array and
        typeof value.length is 'number' and
        typeof value.splice is 'function' and
        not ( value.propertyIsEnumerable 'length' )
        

### isHash: function to detect if an object is a hash ###
isHash = (value) ->
    value and
        typeof value is 'object' and
        not isArray(value)
        

class HTML
    constructor: (type, params, children) ->
        ### create the raw element, or clone if passed an existing element ###
        if typeof type is 'object'
            @element = type.cloneNode()
        else
            @element = document.createElement(type)
        
        ### If params have been passed, set them ###
        if isHash(params)
            for key, val of params
                ### Standard string value? ###
                if typeof val is "string" or typeof val is 'number'
                    @element.setAttribute(key, val)
                else if isArray(val)
                    ### Are we passing a list of data to set? concatenate then ###
                    @element.setAttribute(key, val.join(" "))
                else if isHash(val)
                    ### Are we trying to set multiple sub elements, like a style? ###
                    for subkey,subval of val
                        if not @element[key]
                            throw "No such attribute, #{key}!"
                        @element[key][subkey] = subval
        
        ### If any children have been passed, add them to the element  ###
        if children
            ### If string, convert to textNode using txt() ###
            if typeof children is "string"
                @element.inject(txt(children))
            else
                ### If children is an array of elems, iterate and add ###
                if isArray children
                    for child in children
                        ### String? Convert via txt() then ###
                        if typeof child is "string"
                            @element.inject(txt(child))
                        else
                            ### Plain element, add normally ###
                            @element.inject(child)
                else
                    ### Just a single element, add it ###
                    @element.inject(children)
        return @element
###*
# prototype injector for HTML elements:
# Example: mydiv.inject(otherdiv)
###
HTMLElement.prototype.inject = (child) ->
    if isArray(child)
        for item in child
            # Convert to textNode if string
            if typeof item is 'string'
                item = txt(item)
            this.appendChild(item)
    else
        # Convert to textNode if string
        if typeof child is 'string'
            child = txt(child)
        this.appendChild(child)
    return child

Date.prototype.ISOBare = () ->
    y = this.getFullYear()
    m = (this.getMonth() + 1).pad(2)
    d = this.getDate().pad(2)
    h = this.getHours().pad(2)
    M = this.getMinutes().pad(2)
    return y + "-" + m + "-" + d + " " + h + ":" + M

