text:
struct CivecmI1 <: AbstractCivecm
    endogenous::Matrix{Float64}
    exogenous::Matrix{Float64}
    unrestricted::Matrix{Float64}
    lags::Int64
    α::Matrix{Float64}
    β::Matrix{Float64}
    Γ::Matrix{Float64}
    Hα::Matrix
    Hβ::Matrix
    hβ::Vector
    llConvCrit::Float64
    maxiter::Int64
    verbose::Bool
    Z0::Matrix{Float64}
    Z1::Matrix{Float64}
    Z2::Matrix{Float64}
    R0::Matrix{Float64}
    R1::Matrix{Float64}
end

function civecmI1(
    endogenous::Matrix{Float64};
    exogenous::Matrix{Float64} = zeros(size(endogenous, 1), 0),
    unrestricted::Matrix{Float64} = zeros(size(endogenous, 1), 0),
    lags::Int64 = 2,
    rank::Int64 = size(endogenous, 2))

    ss, p = size(endogenous)
    pexo = size(exogenous, 2)
    punres = size(unrestricted, 2)
    p1 = p + pexo
    iT = ss - lags

    obj = CivecmI1(endogenous,
                   exogenous,
                   unrestricted,
                   lags,
                   Matrix{Float64}(undef, p, rank),
                   Matrix{Float64}(undef, p1, rank),
                   Matrix{Float64}(undef, p, (lags - 1)*p + lags*pexo + punres),
                   Matrix{Float64}(I, p*rank, p*rank),
                   Matrix{Float64}(I, p1*rank, p1*rank),
                   zeros(p1*rank),
                   1.0e-8,
                   5000,
                   false,
                   Matrix{Float64}(undef, iT, p),
                   Matrix{Float64}(undef, iT, p1),
                   Matrix{Float64}(undef, iT, (lags-1)*p + lags*pexo + punres),
                   Matrix{Float64}(undef, iT, p),
                   Matrix{Float64}(undef, iT, p1))
    auxilliaryMatrices!(obj)
    estimateEigen!(obj)
    return obj
end
# civecmI1(endogenous::Matrix{Float64}, exogenous::Matrix{Float64}, lags::Int64) = civecmI1(endogenous, exogenous, lags, size(endogenous, 2))
# civecmI1(endogenous::Matrix{Float64}, lags::Int64) = civecmI1(endogenous, zeros(size(endogenous, 1), 0), lags)
# civecmI1(endogenous::Matrix{Float64}, exogenous::UnitRange, lags::Int64) = civecmI1(endogenous, float64(reshape(exogenous, length(exogenous), 1)), lags)

function Base.getproperty(obj::CivecmI1, s::Symbol)
  if s === :Π
    return obj.α*obj.β'
  else
    return getfield(obj, s)
  end
end

function auxilliaryMatrices!(obj::CivecmI1)
    iT, p  = size(obj.Z0)
    pexo   = size(obj.exogenous, 2)
    punres = size(obj.unrestricted, 2)

    # Endogenous variables
    ## k = 1
    for j = 1:p
        for i = 1:iT
            # First differences
            obj.Z0[i, j] = obj.endogenous[i + obj.lags, j] - obj.endogenous[i + obj.lags - 1, j]

            # Lagged levels
            obj.Z1[i, j] = obj.endogenous[i + obj.lags - 1, j]
        end
    end
    ## Lags (k > 1)
    for k = 1:obj.lags - 1
        for j = 1:p
            for i = 1:iT
                # Lagged first differences
                obj.Z2[i, p*(k - 1) + j] = obj.endogenous[i + obj.lags - k, j] - obj.endogenous[i + obj.lags - k - 1, j]
            end
        end
    end

    # Exogenous variables
    ## k = 1
    for j = 1:pexo
        for i = 1:iT
            # Lagged levels
            obj.Z1[i, p + j] = obj.exogenous[i + obj.lags - 1, j]

            # Lagged first differences
            obj.Z2[i, p*(obj.lags - 1) + j] = obj.exogenous[i + obj.lags, j] - obj.exogenous[i + obj.lags - 1, j]
        end
    end
    ## Lags (k > 1)
    for k = 1:obj.lags - 1
        for j = 1:pexo
            for i = 1:iT
                # Lagged first differences
                obj.Z2[i, p*(obj.lags - 1) + pexo*k + j] = obj.exogenous[i + obj.lags - k, j] - obj.exogenous[i + obj.lags - k - 1, j]
            end
        end
    end

    # Unrestriced variables
    obj.Z2[:,(end - punres + 1):end] = obj.unrestricted[(obj.lags + 1):end, :]

    # Compute concentrated quantities
    if size(obj.Z2, 2) > 0
        obj.R0[:] = mreg(obj.Z0, obj.Z2)[2]
        obj.R1[:] = mreg(obj.Z1, obj.Z2)[2]
    else
        obj.R0[:] = obj.Z0
        obj.R1[:] = obj.Z1
    end

    return obj
end

copy(obj::CivecmI1) = CivecmI1(copy(obj.endogenous),
                               copy(obj.exogenous),
                               copy(obj.unrestricted),
                               obj.lags,
                               copy(obj.α),
                               copy(obj.β),
                               copy(obj.Γ),
                               copy(obj.Hα),
                               copy(obj.Hβ),
                               copy(obj.hβ),
                               obj.llConvCrit,
                               obj.maxiter,
                               obj.verbose,
                               copy(obj.Z0),
                               copy(obj.Z1),
                               copy(obj.Z2),
                               copy(obj.R0),
                               copy(obj.R1))

function show(io::IO, ::MIME"text/plain", obj::CivecmI1)
    print(io, summary(obj))
    print(io, "\n\nα:\n")
    show(io, MIME"text/plain"(), obj.α)
    print(io, "\n\nβᵀ:\n")
    show(io, MIME"text/plain"(), copy(obj.β'))
    print(io, "\n\nΠ:\n")
    show(io, MIME"text/plain"(), obj.α*obj.β')
end

function setrank(obj::CivecmI1, rank::Int64)
    α  = Matrix{Float64}(undef, size(obj.R0, 2), rank)
    β  = Matrix{Float64}(undef, size(obj.R1, 2), rank)
    Hα = Matrix{Float64}(I, size(obj.R0, 2)*rank, size(obj.R0, 2)*rank)
    Hβ = Matrix{Float64}(I, size(obj.R1, 2)*rank, size(obj.R1, 2)*rank)
    hβ = zeros(size(obj.R1, 2)*rank)

    newobj = CivecmI1(obj.endogenous,
                      obj.exogenous,
                      obj.unrestricted,
                      obj.lags,
                      α,
                      β,
                      obj.Γ,
                      Hα,
                      Hβ,
                      hβ,
                      obj.llConvCrit,
                      obj.maxiter,
                      obj.verbose,
                      obj.Z0,
                      obj.Z1,
                      obj.Z2,
                      obj.R0,
                      obj.R1)

    return estimateEigen!(newobj)
end

function restrict(obj::CivecmI1;
    Hβ=nothing,
    hβ=nothing,
    Hα=nothing,
    verbose=false)

    _Hβ = Hβ === nothing ? obj.Hβ : Hβ
    _hβ = hβ === nothing ? obj.hβ : hβ
    _Hα = Hα === nothing ? obj.Hα : Hα

    newobj = CivecmI1(obj.endogenous,
                      obj.exogenous,
                      obj.unrestricted,
                      obj.lags,
                      copy(obj.α),
                      copy(obj.β),
                      copy(obj.Γ),
                      _Hα,
                      _Hβ,
                      _hβ,
                      obj.llConvCrit,
                      obj.maxiter,
                      obj.verbose,
                      obj.Z0,
                      obj.Z1,
                      obj.Z2,
                      obj.R0,
                      obj.R1)

    estimateSwitch!(newobj, verbose=verbose)

    return newobj
end

function estimate!(obj::CivecmI1; method = :switch)
    if method == :switch || method == :Boswijk
        return estimateSwitch!(obj)
    elseif method == :eigen
        return estimateEigen!(obj)
    else
        error("no such method")
    end
end

function estimateEigen!(obj::CivecmI1)
    obj.α[:], svdvals, obj.β[:] = rrr(obj.R0, obj.R1, size(obj.α, 2))
    obj.α[:] = obj.α*Diagonal(svdvals)
    obj.Γ[:] = mreg(obj.Z0 - obj.Z1*obj.β*obj.α', obj.Z2)[1]'
    return obj
end

function estimateSwitch!(obj::CivecmI1; verbose=false)
    iT = size(obj.Z0, 1)
    S11 = rmul!(obj.R1'obj.R1, 1/iT)
    S10 = rmul!(obj.R1'obj.R0, 1/iT)
    ll0 = -floatmax()
    ll1 = ll0
    for i = 1:obj.maxiter
        OmegaInv = inv(cholesky!(residualvariance(obj)))
        aoas11 = kron(obj.α' * OmegaInv * obj.α, S11)
        φ = qr!(obj.Hβ' * aoas11 * obj.Hβ, Val(true)) \
            (obj.Hβ' * (vec(S10 * OmegaInv * obj.α) - aoas11 * obj.hβ))
        obj.β .= reshape(obj.Hβ * φ + obj.hβ, size(obj.β)...)
        γ = qr!(obj.Hα' * kron(OmegaInv, obj.β' * S11 * obj.β) * obj.Hα, Val(true)) \
            (obj.Hα' * vec(obj.β' * S10 * OmegaInv))
        obj.α .= reshape(obj.Hα * γ, size(obj.α, 2), size(obj.α, 1))'
        ll1 = loglikelihood(obj)
        if verbose
            @printf("log-likelihood: %f\n", ll1)
        end
        if abs(ll1 - ll0) < obj.llConvCrit
            break
        end
        ll0 = ll1
    end
    return obj
end

function ranktest(rng::AbstractRNG, obj::CivecmI1, reps::Int)
    _, svdvals, _ = rrr(obj.R0, obj.R1)
    tmpTrace = -size(obj.Z0, 1) * reverse(cumsum(reverse(log.(1 .- svdvals.^2))))
    tmpPVals = zeros(size(tmpTrace))
    rankdist = zeros(reps)
    iT, ip = size(obj.endogenous)
    for i = 1:size(tmpTrace, 1)
        print("Simulation of model H(", i, ")\r")
        for k = 1:reps
            rankdist[k] = I2TraceSimulate(randn(rng, iT, ip - i + 1), ip - i + 1, obj.exogenous)
        end
        tmpPVals[i] = mean(rankdist .> tmpTrace[i])
    end
    print("                                                    \r")
    return TraceTest(tmpTrace, tmpPVals)
end
ranktest(obj::CivecmI1, reps::Int) = ranktest(Random.default_rng(), obj, reps)
ranktest(obj::CivecmI1) = ranktest(obj, 10000)

residuals(obj::CivecmI1) = obj.R0 - obj.R1*obj.β*obj.α'

## I1 ranktest

struct TraceTest
    values::Vector{Float64}
    pvalues::Vector{Float64}
end

function show(io::IO, ::MIME"text/plain", obj::TraceTest)
    println(io, summary(obj))
    @printf(io, "\n Rank    Value  p-value")
    for i = 1:length(obj.values)
        @printf(io, "\n%5d%9.3f%9.3f", i-1, obj.values[i], obj.pvalues[i])
    end
end


text:
using Test
using CLIMA
using CLIMA.LinearSolvers
using CLIMA.GeneralizedConjugateResidualSolver
using CLIMA.GeneralizedMinimalResidualSolver

using StaticArrays, LinearAlgebra, Random

# this test setup is partly based on IterativeSolvers.jl, see e.g
# https://github.com/JuliaMath/IterativeSolvers.jl/blob/master/test/cg.jl
@testset "LinearSolvers small full system" begin
  n = 10

  methods = ((b, tol) -> GeneralizedConjugateResidual(2, b, rtol=tol),
             (b, tol) -> GeneralizedMinimalResidual(b, M=3, rtol=tol),
             (b, tol) -> GeneralizedMinimalResidual(b, M=n, rtol=tol)
            )

  expected_iters = (Dict(Float32 => 7, Float64 => 11),
                    Dict(Float32 => 5, Float64 => 17),
                    Dict(Float32 => 4, Float64 => 10)
                   )

  for (m, method) in enumerate(methods), T in [Float32, Float64]
    Random.seed!(44)

    A = @MMatrix rand(T, n, n)
    A = A' * A + I
    b = @MVector rand(T, n)

    mulbyA!(y, x) = (y .= A * x)

    tol = sqrt(eps(T))
    linearsolver = method(b, tol)

    x = @MVector rand(T, n)
    x0 = copy(x)
    iters = linearsolve!(mulbyA!, linearsolver, x, b; max_iters=Inf)

    @test iters == expected_iters[m][T]
    @test norm(A * x - b) / norm(A * x0 - b) <= tol

    # test for convergence in 0 iterations by
    # initializing with the exact solution
    x = A \ b
    iters = linearsolve!(mulbyA!, linearsolver, x, b; max_iters=Inf)
    @test iters == 0
    @test norm(A * x - b) <= 100eps(T)

    newtol = 1000tol
    settolerance!(linearsolver, newtol)

    x = @MVector rand(T, n)
    x0 = copy(x)
    linearsolve!(mulbyA!, linearsolver, x, b; max_iters=Inf)

    @test norm(A * x - b) / norm(A * x0 - b) <= newtol
    @test norm(A * x - b) / norm(A * x0 - b) >= tol

  end
end

@testset "LinearSolvers large full system" begin
  n = 1000

  methods = (
             (b, tol) -> GeneralizedMinimalResidual(b, M=15, rtol=tol),
             (b, tol) -> GeneralizedMinimalResidual(b, M=20, rtol=tol)
            )

  expected_iters = (
                    Dict(Float32 => (3,3), Float64 => (9, 8)),
                    Dict(Float32 => (3,3), Float64 => (9, 8))
                   )

  for (m, method) in enumerate(methods), T in [Float32, Float64]
    for (i, α) in enumerate(T[1e-2, 5e-3])
      Random.seed!(44)
      A = rand(T, 200, 1000)
      A = α * A' * A + I
      b = rand(T, n)

      mulbyA!(y, x) = (y .= A * x)

      tol = sqrt(eps(T))
      linearsolver = method(b, tol)

      x = rand(T, n)
      x0 = copy(x)
      iters = linearsolve!(mulbyA!, linearsolver, x, b; max_iters=Inf)

      @test iters == expected_iters[m][T][i]
      @test norm(A * x - b) / norm(A * x0 - b) <= tol

      newtol = 1000tol
      settolerance!(linearsolver, newtol)

      x = rand(T, n)
      x0 = copy(x)
      linearsolve!(mulbyA!, linearsolver, x, b; max_iters=Inf)

      @test norm(A * x - b) / norm(A * x0 - b) <= newtol
    end
  end
end

ext: jl


text:
using Test

include("utilites_tests.jl")

include("encoder_tests.jl")

include("partitioning_tests.jl")

include("nodes_tests.jl")

include("discriminators_tests.jl")

include("classifier_tests.jl")

max_stars_repo_name: RafaelFK/ramnet

max_issues_repo_name: RafaelFK/ramnet

max_forks_repo_name: RafaelFK/ramnet


text:
import MechanicalSketch
import MechanicalSketch: color_with_lumin, empty_figure, background, sethue, O,  WI, HE, FS, EM, finish
import MechanicalSketch: settext, setfont, set_scale_sketch, PALETTE, Point
import MechanicalSketch: @import_expand, x_y_iterators_at_pixels
import MechanicalSketch: place_image, lenient_max
import MechanicalSketch: BinLegendVector, draw_legend
import MechanicalSketch: color_with_lumin
import MechanicalSketch.Luxor.ColorTypes: LCHuvA, LCHabA, HSVA, HSLA, LCHabA, RGBA
let
if !@isdefined m²
    @import_expand(m, s, °)
end

BACKCOLOR = color_with_lumin(PALETTE[8], 70)
function restart()
    empty_figure(filename = joinpath(@__DIR__, "test_22.png"))
    background(BACKCOLOR)
    sethue(color_with_lumin(PALETTE[6], 10))
end
restart()

"A complex domain function defined in the unit circle"
foo(z)= hypot(z) <= 1.0m ? z : NaN * z

physwidth = 2.2m
physheight = physwidth
totheight = 2.1 * physheight
set_scale_sketch(totheight, HE)
centers = totheight / 4 * Point.([(-1.2, 1), (1.2, 1),
                                 (-1.2, -1), (0,0) ,(1.2, -1)])

xs, ys = x_y_iterators_at_pixels(;physwidth, physheight)
A = [foo(complex(x, y)) for y in ys, x in xs]
ma = lenient_max(A)

setfont("DejaVu Sans", FS)
str = "Direction ↣ hue\nin five color spaces"
settext(str, O + (-WI/2 + 0.5EM, -0.5HE + 3EM), markup = true)
str = "f: Z ↣ Z ,  f(z) = z \r inside the unit circle"
settext(str, O + (-WI/2 + 0.5EM, 0.5HE - EM), markup = true)

nomcol_1 = HSVA(0.0f0,1.0f0,1.0f0,1.0f0)

# nominal colors for legends, each of a different type but looking the same
nomcols = [nomcol_1,
            convert(HSLA, nomcol_1),
            convert(LCHuvA, nomcol_1),
            convert(LCHabA, nomcol_1),
            convert(RGBA, nomcol_1)]

legends = map(nomcols) do nomco
    BinLegendVector(;operand_example = complex(1.0m, 1.0m),
        max_magn_legend = ma, noof_magn_bins = 8, noof_ang_bins = 40,
        nominal_color = nomco, name = Symbol(string(typeof(nomco))))
end

for (nomco, center, legend) in zip(nomcols, centers, legends)
    colormat = legend.(A)
    ulp, lrp = place_image(center, colormat)
    legendpos = center + (-3EM, 2EM + (ulp[2] - lrp[2]) / 2)
    draw_legend(legendpos, legend)
end

finish()
set_scale_sketch(m) # default

end # let


text:
import GLFW
using ModernGL
include("util.jl")

function is_ci()
	get(ENV, "TRAVIS", "") == "true" || get(ENV, "APPVEYOR", "") == "True" || get(ENV, "CI", "") == "True"
end

if !is_ci() # only do test if not CI... this is for automated testing environments which fail for OpenGL stuff, but I'd like to test if at least including works

    GLFW.Init()
    # OS X-specific GLFW hints to initialize the correct version of OpenGL
    wh = 600
    # Create a windowed mode window and its OpenGL context
    window = GLFW.CreateWindow(wh, wh, "OpenGL Example")
    # Make the window's context current
    GLFW.MakeContextCurrent(window)
    GLFW.ShowWindow(window)
    GLFW.SetWindowSize(window, wh, wh) # Seems to be necessary to guarantee that window > 0

    glViewport(0, 0, wh, wh)

    println(createcontextinfo())
    # The data for our triangle
    data = GLfloat[
        0.0, 0.5,
        0.5, -0.5,
        -0.5,-0.5
    ]
    # Generate a vertex array and array buffer for our data
    vao = glGenVertexArray()
    glBindVertexArray(vao)
    vbo = glGenBuffer()
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW)
    # Create and initialize shaders
    const vsh = """
    $(get_glsl_version_string())
    in vec2 position;
    void main() {
        gl_Position = vec4(position, 0.0, 1.0);
    }
    """
    const fsh = """
    $(get_glsl_version_string())
    out vec4 outColor;
    void main() {
        outColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
    """
    vertexShader = createShader(vsh, GL_VERTEX_SHADER)
    fragmentShader = createShader(fsh, GL_FRAGMENT_SHADER)
    program = createShaderProgram(vertexShader, fragmentShader)
    glUseProgram(program)
    positionAttribute = glGetAttribLocation(program, "position");
    glEnableVertexAttribArray(positionAttribute)
    glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, false, 0, C_NULL)
    # Loop until the user closes the window
    for i=1:500
    	# Pulse the background blue
    	glClearColor(0.0, 0.0, 0.5 * (1 + sin(i * 0.02)), 1.0)
    	glClear(GL_COLOR_BUFFER_BIT)
    	# Draw our triangle
    	glDrawArrays(GL_TRIANGLES, 0, 3)
    	# Swap front and back buffers
    	GLFW.SwapBuffers(window)
    	# Poll for and process events
    	GLFW.PollEvents()
    end
    GLFW.Terminate()

end


text:
using BinaryBuilder, Pkg

name = "PhyML"
version = v"3.3.20210609" # latest passing build
hash = "eb1009ebef100d34696db95301ba7cb55dceeb40"
sources = [
    GitSource("https://github.com/stephaneguindon/phyml.git", hash),
    DirectorySource("./bundled")
]

script = raw"""
cd ${WORKSPACE}/srcdir/phyml
install_license ${WORKSPACE}/srcdir/phyml/COPYING

# disable -march=native flag
for f in ${WORKSPACE}/srcdir/patches/*.patch; do
    atomic_patch -p1 ${f}
done

# generate config scripts
./autogen.sh

# make single-process version
ac_cv_func_malloc_0_nonnull=yes \
ac_cv_func_realloc_0_nonnull=yes \
./configure --enable-phyml --prefix=$prefix --build=${MACHTYPE} --host=${target}
make clean & make -j${nproc}
install -Dvm 755 ./src/phyml${exeext} ${bindir}/phyml${exeext}

# make MPI version

if [[ "$target" == *-mingw* ]]; then
    COMPILER=${target}-gcc
    EXTRALIBS="-lmsmpi -I${includedir} -L${libdir}"
else
    COMPILER=mpicc
    EXTRALIBS=""
fi

ac_cv_func_malloc_0_nonnull=yes \
ac_cv_func_realloc_0_nonnull=yes \
./configure --enable-phyml-mpi --prefix=$prefix --build=${MACHTYPE} --host=${target}
make clean & make -j${nproc} CC=$COMPILER LIBS="${EXTRALIBS}"
install -Dvm 755 ./src/phyml-mpi${exeext} ${bindir}/phymlMPI${exeext}
"""

platforms = supported_platforms()

products = [
    ExecutableProduct("phyml", :phyml),
    ExecutableProduct("phymlMPI", :phymlMPI),
]

dependencies = [
    Dependency(PackageSpec(name="MPICH_jll", uuid="7cb0a576-ebde-5e09-9194-50597f1243b4"); platforms=filter(!Sys.iswindows, platforms)),
    Dependency(PackageSpec(name="MicrosoftMPI_jll", uuid="9237b28f-5490-5468-be7b-bb81f5f5e6cf"); platforms=filter(Sys.iswindows, platforms)),
    Dependency(PackageSpec(name="CompilerSupportLibraries_jll", uuid="e66e0078-7015-5450-92f7-15fbd957f2ae"); platforms=filter(!Sys.isbsd, platforms)),
]

build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies, julia_compat="1.6")

max_stars_repo_name: MichelJuillard/Yggdrasil

max_issues_repo_name: MichelJuillard/Yggdrasil

max_forks_repo_name: MichelJuillard/Yggdrasil


text:
using Weave
if false
    using Pkg
    cd("c:/git/Game2048/")
    Pkg.activate("./weave-env")
end

weave("README.jmd", out_path=:pwd, doctype="github")


text:
__precompile__(false)

using Pkg
pkg"activate . "

import JuliaOpenGL
JuliaOpenGL.main()

max_stars_repo_name: Gilga/JuliaOpenGL

max_issues_repo_name: Gilga/JuliaOpenGL

max_forks_repo_name: Gilga/JuliaOpenGL


text:
# This file is part of the IntervalArithmetic.jl package; MIT licensed

## Promotion rules

promote_rule(::Type{Interval{T}}, ::Type{Interval{S}}) where {T<:Real, S<:Real} =
    Interval{promote_type(T, S)}

promote_rule(::Type{Interval{T}}, ::Type{S}) where {T<:Real, S<:Real} =
    Interval{promote_type(T, S)}

promote_rule(::Type{BigFloat}, ::Type{Interval{T}}) where T<:Real =
    Interval{promote_type(T, BigFloat)}

# convert methods:
convert(::Type{Interval{T}}, x::Real) where {T} = atomic(Interval{T}, x)
convert(::Type{Interval{T}}, x::T) where {T<:Real} = Interval{T}(x)
convert(::Type{Interval{T}}, x::Interval{T}) where {T} = x
convert(::Type{Interval{T}}, x::Interval) where {T} = atomic(Interval{T}, x)

convert(::Type{Interval}, x::Real) = (T = typeof(float(x)); convert(Interval{T}, x))
convert(::Type{Interval}, x::Interval) = x

"""
    atomic(::Type{<:Interval}, x)

Construct the tightest interval of a given type that contains the value `x`.

If `x` is an `AbstractString`, the interval will be created by calling `parse`.

# Examples

Construct an `Interval{Float64}` containing a given `BigFloat`:

```julia
julia> x = big"0.1"
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

julia> i = IntervalArithmetic.atomic(Interval{Float64}, x)
[0.0999999, 0.100001]

julia> i isa Interval{Float64}
true

julia> i.lo <= x <= i.hi
true

julia> i.hi === nextfloat(i.lo)
true
```

Construct an `Interval{Float32}` containing a the real number 0.1 in two ways:

```julia
julia> i1 = IntervalArithmetic.atomic(Interval{Float32}, "0.1")
[0.0999999, 0.100001]

julia> i2 = IntervalArithmetic.atomic(Interval{Float32}, 1//10)
[0.0999999, 0.100001]

julia> i1 === i2
true

julia> i.lo <= 1//10 <= i.hi
true
```
"""
function atomic end

# Integer intervals:
atomic(::Type{Interval{T}}, x::T) where {T<:Integer} = Interval{T}(x)

# Floating point intervals:
atomic(::Type{Interval{T}}, x::AbstractString) where T<:AbstractFloat =
    parse(Interval{T}, x)

@static if Sys.iswindows()  # Windows cannot round properly
    function atomic(::Type{Interval{T}}, x::S) where {T<:AbstractFloat, S<:Real}
        isinf(x) && return wideinterval(T(x))

        Interval{T}( parse(T, string(x), RoundDown),
                     parse(T, string(x), RoundUp) )
    end

    function atomic(::Type{Interval{T}}, x::Union{Irrational,Rational}) where {T<:AbstractFloat}
        isinf(x) && return wideinterval(T(x))

        Interval{T}( T(x, RoundDown), T(x, RoundUp) )
        # the rounding up could be done as nextfloat of the rounded down one?
        # use @round_up and @round_down here?
    end

else
    function atomic(::Type{Interval{T}}, x::S) where {T<:AbstractFloat, S<:Real}
        isinf(x) && return wideinterval(T(x))

        Interval{T}( T(x, RoundDown), T(x, RoundUp) )
        # the rounding up could be done as nextfloat of the rounded down one?
        # use @round_up and @round_down here?
    end
end

function atomic(::Type{Interval{T}}, x::S) where {T<:AbstractFloat, S<:AbstractFloat}
    isinf(x) && return wideinterval(x)#Interval{T}(prevfloat(T(x)), nextfloat(T(x)))
    # isinf(x) && return Interval{T}(prevfloat(x), nextfloat(x))

    xrat = rationalize(x)

    # This prevents that xrat returns a 0//1 when x is very small
    # or 1//0 when x is too large but finite
    if (x != zero(x) && xrat == 0) || isinf(xrat)
        xstr = string(x)
        return Interval(parse(T, xstr, RoundDown), parse(T, xstr, RoundUp))
    end

    return atomic(Interval{T}, xrat)
end

atomic(::Type{Interval{Irrational{T}}}, x::Irrational{S}) where {T, S} =
    float(atomic(Interval{Float64}, x))

function atomic(::Type{Interval{T}}, x::Interval) where T<:AbstractFloat
    Interval{T}( T(x.lo, RoundDown), T(x.hi, RoundUp) )
end

# Complex numbers:
atomic(::Type{Interval{T}}, x::Complex{Bool}) where T<:AbstractFloat =
    (x == im) ? one(T)*im : throw(ArgumentError("Complex{Bool} not equal to im"))

# Rational intervals
function atomic(::Type{Interval{Rational{Int}}}, x::Irrational)
    a = float(atomic(Interval{BigFloat}, x))
    atomic(Interval{Rational{Int}}, a)
end

function atomic(::Type{Interval{Rational{BigInt}}}, x::Irrational)
    a = atomic(Interval{BigFloat}, x)
    atomic(Interval{Rational{BigInt}}, a)
end

atomic(::Type{Interval{Rational{T}}}, x::S) where {T<:Integer, S<:Integer} =
    Interval(x*one(Rational{T}))

atomic(::Type{Interval{Rational{T}}}, x::Rational{S}) where
    {T<:Integer, S<:Integer} = Interval(x*one(Rational{T}))

atomic(::Type{Interval{Rational{T}}}, x::S) where {T<:Integer, S<:Float64} =
    Interval(rationalize(T, x))

atomic(::Type{Interval{Rational{T}}}, x::S) where {T<:Integer, S<:BigFloat} =
    Interval(rationalize(T, x))


text:
from pynextion.widgets import (
    NexButton,
    NexCheckbox,
    NexCrop,
    NexDualStateButton,
    NexGauge,
    NexHotspot,
    NexNumber,
    NexPage,
    NexPicture,
    NexProgressBar,
    NexQRcode,
    NexRadio,
    NexScrollText,
    NexSlider,
    NexText,
    NexWaveform
)
from pynextion.hardware import NexSerialMock

def test_widgets_init():
    controls = [
        NexButton,
        NexCheckbox,
        NexCrop,
        NexDualStateButton,
        NexGauge,
        NexHotspot,
        NexNumber,
        NexPage,
        NexPicture,
        NexProgressBar,
        NexQRcode,
        NexRadio,
        NexScrollText,
        NexSlider,
        NexText,
        NexWaveform
    ]
    nexSerial = NexSerialMock()
    name, pid, cid = "t0", 0, 0
    for ctl in controls:
        ctl(nexSerial, name, pid=pid, cid=cid)


text:
# AUTO GENERATED FILE - DO NOT EDIT

export 'feffery'_antdavatar

"""
    'feffery'_antdavatar(;kwargs...)

An AntdAvatar component.

Keyword arguments:
- `id` (String; optional)
- `alt` (String; optional)
- `className` (String; optional)
- `gap` (Real; optional)
- `icon` (String; optional)
- `loading_state` (optional): . loading_state has the following type: lists containing elements 'is_loading', 'prop_name', 'component_name'.
Those elements have the following types:
  - `is_loading` (Bool; optional): Determines if the component is loading or not
  - `prop_name` (String; optional): Holds which property is loading
  - `component_name` (String; optional): Holds the name of the component that is loading
- `mode` (a value equal to: 'text', 'icon', 'image'; optional)
- `shape` (a value equal to: 'circle', 'square'; optional)
- `size` (optional): . size has the following type: Real | a value equal to: 'large', 'small', 'default' | lists containing elements 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'.
Those elements have the following types:
  - `xs` (Real; optional)
  - `sm` (Real; optional)
  - `md` (Real; optional)
  - `lg` (Real; optional)
  - `xl` (Real; optional)
  - `xxl` (Real; optional)
- `src` (String; optional)
- `srcSet` (String; optional)
- `style` (Dict; optional)
- `text` (String; optional)
"""
function 'feffery'_antdavatar(; kwargs...)
        available_props = Symbol[:id, :alt, :className, :gap, :icon, :loading_state, :mode, :shape, :size, :src, :srcSet, :style, :text]
        wild_props = Symbol[]
        return Component("'feffery'_antdavatar", "AntdAvatar", "feffery_antd_components", available_props, wild_props; kwargs...)
end

max_stars_repo_name: ReilYoung/feffery-antd-components

max_issues_repo_name: ReilYoung/feffery-antd-components

max_forks_repo_name: ReilYoung/feffery-antd-components


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder

name = "Mineos"
version = v"1.0"

# Collection of sources required to build Mineos
sources = [
    "https://github.com/anowacki/mineos.git" =>
    "e2558b486d7656ef112608a8776643da66dc87cf",
]

# Bash recipe for building across all platforms
script = raw"""
cd ${WORKSPACE}/srcdir/mineos
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target} --disable-doc
make
make install
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = expand_gfortran_versions(supported_platforms())

# The products that we will ensure are always built
products = [
    ExecutableProduct("simpledit", :simpledit),
    ExecutableProduct("endi", :endi),
    ExecutableProduct("eigcon", :eigcon),
    ExecutableProduct("eigen2asc", :eigen2asc),
    ExecutableProduct("green", :green),
    ExecutableProduct("syndat", :syndat),
    ExecutableProduct("minos_bran", :minos_bran),
    ExecutableProduct("cucss2sac", :cucss2sac)
]

# Dependencies that must be installed before this package can be built
dependencies = [
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
using CSV
using DataFrames
using Plots
include("/Users/anguslewis/Documents/SFFMProject/DFQExamples.jl/plot_utils.jl")

@halfwidth_plot_defaults()

plotlyjs()
function p()
ks_data = CSV.read((@__DIR__)*"/../data/meshs_ks_func_count_6.csv",DataFrame)

plot()
linestyles_vec = [:solid,:dash,:dashdot]
markerstyles_vec = [:cross,:diamond,:circle]
colours = [1;2;4]

for (c,col) in enumerate(names(ks_data))
    plot!(log10.(1:2:21),ks_data[:,col],
        label=col,linestyle=linestyles_vec[c],
        marker=markerstyles_vec[c],color=colours[c],
        linewidth=2)
end
plot!(xlabel="Dimension")
plot!(ylabel="Error"); error_ticks!(plot!())
plot!(title="KS error")
# plot!(legend=(0.7,0.65))
plot!()
@add_lines!(ks_data,("Unif","QBDRAP"),@__DIR__)
savefig((@__DIR__)*"/meshs_ks_error_formatted.pdf")
end
p()

function p()
l2_pdf_data = CSV.read((@__DIR__)*"/../data/meshs_l2_pdf_func_count_6.csv",DataFrame)
colours = [1;2;4]
plot()
linestyles_vec = [:solid,:dash,:dashdot]
markerstyles_vec = [:cross,:diamond,:circle]
for (c,col) in enumerate(names(l2_pdf_data))
    plot!(log10.(1:2:21),l2_pdf_data[:,col],
        label=col,linestyle=linestyles_vec[c],
        marker=markerstyles_vec[c],color=colours[c],
        linewidth=2)
end
plot!(xlabel="Dimension")
plot!(ylabel="Error"); error_ticks!(plot!())
plot!(title="L² error - PDF")
# plot!(legend=(0.7,0.65))
plot!(yticks=-12:3:0)
plot!()
@add_lines!(l2_pdf_data,("Unif","QBDRAP"),@__DIR__)
savefig((@__DIR__)*"/meshs_l2_pdf_error_formatted.pdf")
end
p()


text:
import Pkg; Pkg.activate(@__DIR__); Pkg.instantiate()

using RigidBodyDynamics
using LinearAlgebra
using MeshCatMechanisms
using MeshCat
using StaticArrays
using SparseArrays
using ForwardDiff
const FD = ForwardDiff

include("utils.jl")
include("constraint.jl")
include("opt-setup.jl")
include("properties.jl")
include("control.jl")
include("vis.jl")

#Initial Conditions
rb = [0.0; 0.0; 0.5]  # start 0.5 meters above the ground
Qb = [1.0; 0; 0; 0]
q0 = 30*pi/180;
q1 = 120*(pi/180)
q2 = 150*(pi/180)
q3 = -120*(pi/180)
a_target = [-40*pi/180; -140*pi/180]

Tf = 1
h = 0.01
thist = 0:h:Tf
N = length(thist)

pb = rb + rotate(Qb, l_cb)  # position vector from world frame to *JOINTS* 0 and 2

Qb0 = Expq([0, q0, 0])  # quaternion from base to link 0
Q0 = L(Qb)*Qb0  # quaternion from world frame to link 0
r0 = pb + rotate(Q0, l_c0)

Q01 = Expq([0, q1, 0])  # quaternion from link 0 to link 1
Q1 = L(Q0)*Q01  # quaternion from world frame to link 1
r1 = pb + rotate(Q0, l0) + rotate(Q1, l_c1)

Qb2 = Expq([0, q2, 0])  # quaternion from base to link 2
Q2 = L(Qb)*Qb2  # quaternion from world frame to link 2
r2 = pb + rotate(Q2, l_c2)

Q23 = Expq([0, q3, 0])  # quaternion from base to link 2
Q3 = L(Q2)*Q23  # quaternion from world frame to link 2
r3 = pb + rotate(Q2, l2) + rotate(Q3, l_c3)

Qb .= Qb/norm(Qb)
Q0 .= Q0/norm(Q0)
Q1 .= Q1/norm(Q1)
Q2 .= Q2/norm(Q2)
Q3 .= Q3/norm(Q3)

q_0 = [rb; Qb; r0; Q0; r1; Q1; r2; Q2; r3; Q3]  # initial state

# make gravity zero for first two timesteps
ghist = repeat([0 0 0], N)'
ghist[:, 1] = [0 0 0]
ghist[:, 2] = [0 0 0]

global const n_c = size(con(q_0))[1]  # number of constraint function rows corresponding to lagrange multipliers
global const n_q = size(q_0)[1]  # number of state rows, 35

#Solve with IPOPT
n_n = 1 # number of normal forces, MUST UPDATE MANUALLY
n_b = 2 # number of friction forces (x and y), MUST UPDATE MANUALLY
n_λf = 1  # size of λf
n_s = 2  # number of complementary slackness constraints, MUST UPDATE MANUALLY
n_nlp = n_q + n_c + n_s + n_b + n_λf + n_n  # size of decision variables
n_c_ineq = 0  # no. of ineq constraints corresponding to λ (NOT λf), MUST UPDATE MANUALLY
n_c_eq = n_c-n_c_ineq
n_ineq = 4  # total number of inequality constraints, MUST UPDATE MANUALLY
n_eq = 30+5+n_c+n_b  # number of equality constraints
m_nlp = n_eq + n_ineq  # size of constraint! output

#Specify the indicies of c (constraint output) that should be non-negative.
#The rest will be treated as equality constraints.
#This can vary depending on how you stacked up c.
nonnegative_constraint_indices = (n_eq+1:m_nlp)
nlp_prob = ProblemMOI(n_nlp,m_nlp, idx_ineq=nonnegative_constraint_indices);

#Initial conditions
qhist = zeros(n_q,N)
qhist[:,1] .= q_0
qhist[:,2] .= q_0  # this may need to be fixed

λhist = zeros(n_c,N-1)
shist = zeros(n_s,N-1)

bhist = zeros(n_b,N-1)
λfhist = zeros(n_b,N-1)
nhist = zeros(n_n, N-1)

global F = u_f([0.0; 0.0], q_0)
global F_prev = u_f([0.0; 0.0], q_0)
Fhist = zeros(30, N)
global k = 0

for kk = 2:(N-1)

    global k = kk
    print("position = ",a_act(qhist[:, k])*180/pi, " target = ", a_target*180/pi, "\n")
    a = a_act(qhist[:, k])
    a_prev = a_act(qhist[:, k-1])

    if k <= 3  # enforce no input for first two timesteps
        global F = u_f([0.0; 0.0], q_0)
    else
        # global F = u_f([0.0; 0.0], qhist[:, k])
        global F = a_control(a_target, a, a_vel(a, a_prev, h), qhist[:, k])
    end

    z_guess = [qhist[:,k]; zeros(n_c); ones(n_s); zeros(n_b); ones(n_b); zeros(n_n)]
    z_sol = ipopt_solve(z_guess, nlp_prob, tol=1.0e-3,c_tol=1.0e-3, max_iter=2000, print=2);
    qhist[:,k+1] .= z_sol[1:n_q]
    λhist[:,k] .= z_sol[n_q + 1:n_q + n_c]
    shist[:,k] .= z_sol[n_q + n_c + 1:n_q + n_c + n_s]
    bhist[:,k] .= z_sol[n_q + n_c + n_s + 1:n_q + n_c + n_s + n_b]
    λfhist[:,k] .= z_sol[n_q + n_c + n_s + n_b + 1:n_q + n_c + n_s + n_b + n_λf]
    nhist[:,k] .= z_sol[n_q + n_c + n_s + n_b + n_λf + 1:end]

    global F_prev = copy(F)
    Fhist[:, k] = copy(F)
    # e = constraint_check(z_sol, 1.0e-3)  # print("\n", e, "\n")
    # f e == true; break; end
    print("Simulation ", round(kk/(N-1)*100, digits=3), " % complete \n")
    # flush(stdout)

    # if kk/(N-1)*100 > 40; break; end

end

function signed_d()
    hf = zeros(N)
    for i in 1:(N-1)
        r3 = qhist[29:31, i]
        Q3 = qhist[32:35, i]
        hf[i] = r3[3] + rotate(Q3, lee-l_c3)[3] # - 0.025 # position of foot
    end
    return hf
end

function angle_look()
    an = zeros(N)
    for i in 1:(N-1)
        Q0 = qhist[11:14, i]
        Q1 = qhist[18:21, i]
        an[i] = pi - anglesolve(L(Q0)'*Q1)
    end
    return an
end

function angle_y_look()
    an = zeros(N-1)
    for i in 1:(N-1)
        Qb = qhist[4:7, i]
        Q0 = qhist[11:14, i]
        Q1 = qhist[18:21, i]
        an[i] = -angle_y(Qb, Q0)
    end
    return an
end

plot = true # for now manually change this
fnt = pl.font("Times Roman")
thyme = collect(thist)
if plot == true
    ph = pl.plot(thist,signed_d(), title="signed dist from foot to ground plane")
    pbz = pl.plot(thist,qhist[3,:], title="height of body")
    plam = pl.plot(λhist[n_c,:],title="contact force")  # ylims = (0,20))
    pslack = pl.plot(thyme[1:N-1], shist',title="slackvar")
    panbt = pl.plot(thyme[1:N-1], -angle_y_look().*180/pi,title="Angle Between Q0 and Q1",
        xlabel="Time (s)", ylabel="Angle (Degrees)", ylim=(0, 60), titlefont=fnt, guidefont=fnt,
        tickfont=fnt, legendfont=fnt, size=(1200,800), fmt = :png, thickness_scaling=2)
    pF0 = pl.plot(thist, Fhist[11, :],title="torque acting on link0")
    pF1 = pl.plot(thist, Fhist[23, :],title="torque acting on link2")
    pl.display(ph)
    pl.display(pbz)
    pl.display(plam)
    pl.display(pslack)
    pl.display(panbt)
    # pl.savefig("panbt")
    pl.display(pF0)
    pl.display(pF1)
end

urdf = false  # for now manually change this

if urdf == false
    anim_init = geom_init
    anim = geom_vis
else
    print("Warning: urdf visualization mode not as truthful as geometric")
    anim_init = urdf_init
    anim = urdf_vis
end

mvis = anim_init()
print("\n Visualization starting in 5 seconds \n")
sleep(5)
# qhist = qhist[vec(mapslices(col -> any(col .!= 0), qhist, dims = 2)), :]  # delete nonzero rows
for j in 1:5
    print("\n Visualization starting now, replay #", j, "\n")
    anim(mvis, qhist, h, 0.1)
end
print("\n Visualization ended \n")

max_stars_repo_name: bbokser/hopper-sim

max_issues_repo_name: bbokser/hopper-sim

max_forks_repo_name: bbokser/hopper-sim


text:
# This file is a part of Julia. License is MIT: http://julialang.org/license

export latex

function wrapblock(f, io, env)
    println(io, "\\begin{", env, "}")
    f()
    println(io, "\\end{", env, "}")
end

function wrapinline(f, io, cmd)
    print(io, "\\", cmd, "{")
    f()
    print(io, "}")
end

# Block elements

latex(io::IO, md::MD) = latex(io, md.content)

function latex(io::IO, content::Vector)
    for c in content
        latex(io, c)
    end
end

function latex{l}(io::IO, header::Header{l})
    tag = l < 4 ? "sub"^(l-1) * "section" : "sub"^(l-4) * "paragraph"
    wrapinline(io, tag) do
        latexinline(io, header.text)
    end
    println(io)
end

function latex(io::IO, code::Code)
    wrapblock(io, "verbatim") do
        # TODO latex escape
        println(io, code.code)
    end
end

function latexinline(io::IO, code::Code)
    wrapinline(io, "texttt") do
        print(io, code.code)
    end
end

function latex(io::IO, md::Paragraph)
    for md in md.content
        latexinline(io, md)
    end
    println(io)
end

function latex(io::IO, md::BlockQuote)
    wrapblock(io, "quote") do
        latex(io, md.content)
    end
end

function latex(io::IO, md::List)
    env = md.ordered ? "enumerate" : "itemize"
    wrapblock(io, env) do
        for item in md.items
            print(io, "\\item ")
            latexinline(io, item)
            println(io)
        end
    end
end

function writemime(io::IO, ::MIME"text/latex", md::HorizontalRule)
    println(io, "\\rule{\\textwidth}{1pt}")
end

# Inline elements

function latexinline(io::IO, md::Vector)
    for c in md
        latexinline(io, c)
    end
end

function latexinline(io::IO, md::String)
    latexesc(io, md)
end

function latexinline(io::IO, md::Bold)
    wrapinline(io, "textbf") do
        latexinline(io, md.text)
    end
end

function latexinline(io::IO, md::Italic)
    wrapinline(io, "emph") do
        latexinline(io, md.text)
    end
end

function latexinline(io::IO, md::Image)
    wrapblock(io, "figure") do
        println(io, "\\centering")
        wrapinline(io, "includegraphics") do
            print(io, md.url)
        end
        println(io)
        wrapinline(io, "caption") do
            latexinline(io, md.alt)
        end
        println(io)
    end
end

function latexinline(io::IO, md::Link)
    wrapinline(io, "href") do
        print(io, md.url)
    end
    print(io, "{")
    latexinline(io, md.text)
    print(io, "}")
end

const _latexescape_chars = @compat(Dict{Char, String}(
   '~'=>"{\\sim}", '^'=>"\\^{}", '\\'=>"{\\textbackslash}"))
for ch in "&%\$#_{}"
    _latexescape_chars[ch] = "\\$ch"
end

function latexesc(io, s::String)
    for ch in s
        print(io, get(_latexescape_chars, ch, ch))
    end
end

latex(md) = sprint(latex, md)
latexinline(md) = sprint(latexinline, md)
latexesc(s) = sprint(latexesc, s)

writemime(io::IO, ::MIME"text/latex", md::MD) = latex(io, md)
#writemime(io::IO, ::MIME"text/latex", md::MD) = writemime(io, "text/plain", md)


text:
## General Widget properties

## :value is the main value
@doc "get the `:value` property, the primary value for a control" ->
getValue(o::WidgetModel) = getValue(o.model)

@doc """
Set the `:value` property, the primary value for a control

The `signal::Bool` argument indicates if any events should be signalled.

""" ->
function setValue(o::WidgetModel, value; signal::Bool=true)
    setValue(o.model, value; signal=signal)
end

## :items is use for vector models to provide the items to select from
@doc """
Get the `:items` property. Used by widgets with VectorModels -- that
is, those widgets which are used to select 0, 1 or more from a
collection.
""" ->
getItems(o::WidgetVectorModel) = getItems(o.model)

@doc "set the `:items` property" ->
setItems(o::WidgetVectorModel, value) = setItems(o.model, value)

## :enabled indicates if a widget is sensitive to user input
@doc "Get the `:enabled` property. This indicates if a widget is sensitive (or not) to user input" ->
getEnabled(o::Widget) = getEnabled(o.toolkit, o)

@doc "Set the `:enabled` property. This indicates if a widget is sensitive (or not) to user input" ->
setEnabled(o::Widget, value::Bool) = setEnabled(o.toolkit, o, value)

## :visible indicates if a widget is drawn to the screen
@doc "Get the `:visible` property. Indicates if a widget is shown" ->
getVisible(o::Widget) = getVisible(o.toolkit, o)

@doc "Set the `:visible` property. Indicates if a widget is shown" ->
setVisible(o::Widget, value::Bool) = setVisible(o.toolkit, o, value)

## :focus inidicates if a control has keyboard focus
@doc "Get the `:focus` property" ->
getFocus(o::Widget) = getFocus(o.toolkit, o)

@doc "Set the `:focus` property. The control with focus receive keyboard input" ->
setFocus(o::Widget, value::Bool) = setFocus(o.toolkit, o, value)

@doc "Get the `:context` property. Context used to pass information to context menus" ->
getContext(o::Widget) = o.attrs[:context]

@doc "Set the `:context` property. Contextis used to pass information to context menus" ->
setContext(o::Widget, ctx) = o.attrs[:context] = ctx

@doc "Get the `:size` property. Indicates the size request of a widget. Can be useful for top-level windows" ->
getSize(o::Widget) = getSize(o.toolkit, o)

@doc "Set the `:size` property. Indicates the size request of a widget. Specified by a `Int[w,h]`" ->
setSize{T <: Int}(o::Widget, sz::Vector{T}) = setSize(o.toolkit, o, sz)

@doc """
Get the `:sizepolicy` property.

The `:sizepolicy` determines how a widget expands to fill its allocated
space.  The value is specified as a tuple (x,y) with each being be
one of `:fixed`, `:expand`, or `nothing`.
""" ->
function getSizepolicy(o::Widget)
    if haskey(o.attrs, :sizepolicy)
        o.attrs[:sizepolicy]
    else
        (nothing, nothing)
    end
end

@doc "set the `:sizepolicy` property" ->
function setSizepolicy(o::Widget, value)
    ## must have proper policy (nothing, :fixed, :expand)
    x, y = value
    ## check
    setSizepolicy(o.toolkit, o, value)

end

@doc """
Get the `:alignment` property.

The `:alignment` property is used to determine how a control is aligned in its
allocated space. The value is specified as a tuple of the form  (xalign, yalign)
with

- xalign in (:left, :right, :center, :justify)
- yalign one of (:top, :bottom, :center)
""" ->
function getAlignment(o::Widget)
    if haskey(o.attrs, :alignment)
        o.attrs[:alignment]
    else
        (nothing, nothing)
    end
end

@doc "Set the `:alignment` property" ->
function setAlignment(o::Widget, value) #x::Union(Symbol, Nothing), y::Union(Symbol, Nothing))

    x, y = value
    if isa(x, Symbol)
        if !(x in [:left, :right, :center, :justify])
            error("x-alignment is one of :left, :right, :center, :justify or nothing.")
        end
    end
        if isa(y, Symbol)
            if !(y in [:top, :bottom, :center])
                error("y-alignment is one of :top, :bottom, :center or nothing.")
            end
        end
    o.attrs[:alignment] = value

    ## not enough to use which, as it shows -- not returns.
    if length(methods(setAlignment, map(typeof, (o.toolkit, o, value)))) > 0
        setAlignment(o.toolkit, o, value)
    end

end

## for box containers, (not tcltk, but Qt)
@doc "Get the `:stretch` property for a widget. XXX" ->
getStretch(o::Widget) = haskey(o.attrs, :stretch) ? o.attrs[:stretch] : 0

@doc "Set then `:stretch` property for a widget. XXX" ->
setStretch(o::Widget, stretch::Int) = o.attrs[:stretch] = stretch

## icontheme
@doc "Get the `:icontheme` property for a widget. Not yet implemented" ->
getIcontheme(o::Widget) = getIcontheme(o.parent)
getIcontheme(o::Window) = o.attrs[:icontheme]

@doc "Set the `:icontheme` property for a widget. Not yet implemented" ->
setIcontheme(o::Widget, value::Symbol) = setIcontheme(o.parent, value)
setIcontheme(o::Window, value::Symbol) = o.attrs[:icontheme] = value

## get widget. Mostly just obj.o, but there may be exceptions
getWidget(o::Widget) = getWidget(o.toolkit, o)
getBlock(o::Widget) = getBlock(o.toolkit, o)

## list Widget properties
@doc """
List properties available for a  widget

The properties are retrieved and set using indexing notation, where the property is specified through
a symbol, as in `:size` or `:enabled`.

The underlying toolkits provide significantly more properties to control a widgets display or behaviour.
""" ->
list_props(::@PROP("Widget")) = {:value => "Value of object",
                                 :items => "Any items to select from",
                                 :enabled => "is widget sensitive to user input",
                                 :visible => "is widget drawn",
                                 :size => "widget size (width, height) in pixels",
                                 :focus => "Does control have focus",
                                 :sizepolicy => "(x,y) with x and y being nothing, :fixed or :expand",
                                 :alignment => "(x,y) with x in (:left, :right, :center, :justify), y in (:top, :bottom, :center)",
                                 :icontheme => "set theme for any icons to be added"
                                 }

## WidgetModel
##
## The signals are emitted by the model. These definitions bring
## connect, disconnect and notify to the widget for convenience
connect(o::WidgetModel, signal::String, obj, slot::Function) = connect(o.model, signal, obj, slot)
connect(o::WidgetModel, signal::Symbol, obj, slot::Function) = connect(o, string(signal), obj, slot)
connect(o::WidgetModel, signal::String, slot::Function) = connect(o.model, signal, nothing, slot)
connect(o::WidgetModel, signal::Symbol, slot::Function) = connect(o, string(signal), slot)
connect(slot::Function, o::WidgetModel, signal::Union(Symbol, String)) = connect(o, signal, slot)

disconnect(o::WidgetModel, id::String) = disconnect(o.model, id)

notify(o::WidgetModel, signal::String, args...) = notify(o.model, signal, args...)
notify(o::WidgetModel, signal::Symbol, args...) = notify(o, string(signal), args...)

##################################################
## Basic widgets for drawing to window

## Label

type Label <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Basic label widget

## Arguments:
* `parent::Container` parent container
* `value::Union(ItemModel, String)` either a model (for sharing) or string.

## Signals:
* `valueChanged (value)` called when label text is updated.

## Example:
```julia
w = window(title="label")
l = label(w, "label")
push!(w, l)
l[:value] = "new label"
```

""" ->
function label(parent::Container, model::Model; kwargs...)
    widget, block = label(parent.toolkit, parent, model)
    obj = Label(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end
label(parent::Container, value::String) = label(parent, ItemModel(value))
label(parent::Container, value::Number) = label(parent, string(value))
setValue(o::Label, value::Number; signal::Bool=true) = setValue(o, string(value); signal=signal)

## Separator
type Separator <: Style
    o
    block
    parent
    toolkit
    attrs
end

@doc """
Add a horizontal or vertical line to a layout

## Arguments:
* `orientation::Symbol` one of `:horizontal` (default) or `:vertical`

## Example
```julia
w = window(title="separator")
g = vbox(w); push!(w, g)
l1 = label(g, "top label")
s = separator(g)
l2 = label(g, "bottom label")
append!(g, [l1, s, l2])
```

""" ->
function separator(parent::Container; orientation::Symbol=:horizontal)
    widget, block = separator(parent.toolkit, parent, orientation=orientation)
    Separator(widget, block, parent, parent.toolkit, Dict())
end

##################################################
## Button widget

type Button <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Primary control to initiate an action

## Arguments:
* `parent::Container` a parent container
* `value::Union(ItemModel, String)` If a model, value is shared. If a string, used as label

## Signals:
* `clicked ()`: called when clicked
* `valueChanged (value)`: called when label is changed

## Examples:

```julia
w = window(title="buttons")
g = vbox(w); push!(w, g)
b1 = button(g, "click me")
push!(g, b1)
connect(b1, :clicked, () -> b1[:value] = "that tickled")
```

""" ->
function button(parent::Container, model::Model; kwargs...)
    widget, block = button(parent.toolkit, parent, model)
    obj = Button(widget, block, model,  parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end
button(parent::Container, value::String; kwargs...) = button(parent, ItemModel(value); kwargs...)
button(parent::Container, value::Number; kwargs...) = button(parent, string(value); kwargs...)

@doc "Set `:icon` property for a button. Icon specified by `Icon`, symbol or string." ->
function setIcon(object::Button, icon::Icon;
                 theme::Union(Nothing, Symbol) = nothing,
                 size::Union(Nothing, Vector{Int}) = nothing)
    if theme == nothing
        theme = object[:icontheme]
    end
    if size == nothing
        size = [16, 16]
    end
    setIcon(object.toolkit, object, icon)#; theme=theme, size=size)
end
setIcon(object::Button, nm::Union(Symbol, String)) = setIcon(object, icon(nm))
setIcon(object::Button, nm::Nothing) = setIcon(object.toolkit, object, StockIcon(nothing, nothing))

list_props(::@PROP("Button")) = {:icon => "Set accompanying icon"}
##################################################
## Text controls

## LineEdit

## signals
## (valueChanged, (value))
## (activated, ())
## (keystroke, (key))

type LineEdit <: WidgetModel
    o
    block
    model
    parent
    toolkit
    coerce
    attrs
end

@doc """
Single line text entry

## Arguments:
* `value` is an item model (for sharing) or a string or a number
* `coerce` is a function to be called on the string value in the edit
box before getValue. Even if a number is specified as the value,
the return will be a string unless coerced.

## Signals:
* `editingFinished` (value) called when <return> key is pressed or blur
* `focusIn`  called on focus in event
* `focusOut` (value) called on focus out event
* `textChanged` (key) called on each keystroke
* `valueChanged` (value) called on each change, even keystrokes

## TODO
* typeahead values
* validation
* undo/redo stack
* ...

## Examples
```julia
w = window(title="lineedit")
f = formlayout(w); push!(w, f)

le1 = lineedit(f, "test")
push!(f, le1, "vanilla")

le2 = lineedit(f, "")
le2[:typeahead] = ["one", "two", "three"]
push!(f, le2, "typeahead")

le3 = lineedit(f, "", placeholdertext="write something here")
push!(f, le3, "placeholder")

le4 = lineedit(f, "", placeholdertext="type here to get echo")
connect(le4, :textChanged) do key
    println("Typed", key)
end
push!(f, le4, "echo")
```

""" ->
function lineedit(parent::Container, model::Model; coerce::Union(Nothing, Function)=nothing, kwargs...)
    widget, block = lineedit(parent.toolkit, parent, model)

    obj = LineEdit(widget, block, model,  parent, parent.toolkit, coerce, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end

    obj
end
lineedit(parent::Container, value::String=""; kwargs...) = lineedit(parent, ItemModel(value); kwargs...)
lineedit(parent::Container, value::Number; kwargs...) = lineedit(parent, string(value); kwargs...)

function setValue(obj::LineEdit, value; signal::Bool=true)
    value = string(value)
    if !isa(obj.coerce, Nothing)
        value = string(obj.coerce(value))
    end
    setValue(obj.model, value ; signal=signal)
end

## Call coerce if present. If can't be coerced, returns nothing
function getValue(obj::LineEdit)
    val = getValue(obj.model)
    isa(obj.coerce, Nothing) ? val : try obj.coerce(string(val)) catch e nothing end
end

## placeholder text
getPlaceholdertext(obj::LineEdit) = obj.attrs[:placeholdertext]
function setPlaceholdertext(obj::LineEdit, txt::String)
    obj.attrs[:placeholdertext] = txt
    notify(obj.model, "placeholderTextChanged", txt)
end

## typeahead
setTypeahead{T<:String}(obj::LineEdit, items::Vector{T}) = setTypeahead(obj.toolkit, obj, items)

list_props(::@PROP("LineEdit")) = {:placeholdertext => "Text to display when widget has no value and no focus.",
                                   :typeahead => "Items to use for type ahead suggestions (Qt only)"
                                   }

## TextEdit
type TextEdit <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Multi-line text edit box

Text can be changed by setting the `:value` property. To append text, use `push!`.

## Arguments:
* `parent::Container`: parent container
* `value::Union(ItemModel, String)`: inital string or an `ItemModel` to share

## Signals:
* `activated` (value) called when blur occurs
* `focusIn`  called on focus out event
* `focusOut` (value) called on focus out event
* `textChanged` (key) called on each keystroke
* `valueChanged` (value) called on each change, even keystrokes
*

## TODO:
* set size, font, ...
* get just the selection
* selection changed signal
* ...

## Examples:
```julia
w = window()
t = textedit(w, "")
t[:value] = "Some new text"
push!(w, t)

connect(t, :focusIn, () -> println("Text edit got focus"))
```

""" ->
function textedit(parent::Container, model::Model; kwargs...)
    widget, block = textedit(parent.toolkit, parent, model)

    obj = TextEdit(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end

    obj
end
textedit(parent::Container, value::String=""; kwargs...) = textedit(parent, ItemModel(value); kwargs...)
textedit(parent::Container, value::Number; kwargs...) = textedit(parent, string(value); kwargs...)

## some presumably common things of interest
setValue(obj::TextEdit, value::Vector) = setValue(obj, join(map(string, value), "\n"))
setValue(obj::TextEdit, value::Number) = setValue(obj, string(value))

## add to textedit via push!
push!(o::TextEdit, value) = push_textedit(o.toolkit, o, value)

##################################################
##
## Selection widgets

## checkbox
type CheckBox <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
standard toggle for true/false values. Optional label.

## Arguments:

 * `value::Bool` initial state of widget
 * `label::MaybeString` optional label

## Signals:

 * `valueChanged (value)` called when widget toggles state.

## Examples:

```julia
w = window(title="checkbox")
cb = checkbox(w, true, "Check me, please")
push!(w, cb)
connect(cb, :valueChanged) do value
    println("Changed to ", value)
end
```

""" ->
function checkbox(parent::Container, model::Model, label::Union(Nothing, String); kwargs...)
    widget, block = checkbox(parent.toolkit, parent, model, label)
    obj = CheckBox(widget, block, model, parent, parent.toolkit, Dict())
    obj[:label] = label
    for (k, v) in kwargs
        obj[k] = v
    end

    obj
end

function checkbox(parent::Container, value::Bool=true, label::Union(Nothing, String)=nothing; kwargs... )
    model=ItemModel(value)
    checkbox(parent, model, label; kwargs...)
end

getLabel(o::CheckBox) =  o.attrs[:label]
function setLabel(o::CheckBox, value::String)
    o.attrs[:label] = value
    setLabel(o.toolkit, o, value)
end
setLabel(o::CheckBox, value::Nothing)  = setLabel(o, "")

list_props(::@PROP("CheckBox")) = {:label => "checkbox label"}

##################################################
##
## WidgetVectorModel is used for selection
##

abstract StrictWidgetVectorModel <: WidgetVectorModel
function setValue(o::StrictWidgetVectorModel, value; signal::Bool=true)
    ## is value in vector?
    if isa(value, Nothing) || any(value .== o[:items])
        setValue(o.model, value; signal=signal)
    end
end

type RadioGroup <: StrictWidgetVectorModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Radio button group

Value, not index, is used to store state.

## Arguments:
* `items`: items to choose from
* `value=items[1]`: initial value for selection
* `orientation::Symbol=:horizontal` (or `:vertical`).

## Signals:
* `valueChanged (value)` called when selected value is updated

## TODO
* how to set items to be selected? (need `setItems` method)

## Examples
```julia
w = window(title="radiogroup")
items = ["one", "two", "three"]
rg = radiogroup(w, items)
push!(w, rg)
connect(rg, :valueChanged, val -> println(val))
rg[:value] = "two"
```

""" ->
function radiogroup(parent::Container, model::VectorModel; orientation::Symbol=:horizontal, kwargs...)
    widget, block = radiogroup(parent.toolkit, parent, model, orientation=orientation)
    obj = RadioGroup(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

function radiogroup(parent::Container, items::Union(Range,Vector), value=items[1]; orientation::Symbol=:horizontal, kwargs...)
    model = VectorModel(items, value)
    radiogroup(parent, model, orientation=orientation, kwargs...)
end

type ButtonGroup <: StrictWidgetVectorModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """

A buttongroup is like a radio group with toggle buttons
(toolbar style). The group can be exclusive (one selected only) or not

Call as `buttongroup(parent, items)` or `buttongroup(parent, items, initialselection)`.

## Arguments:

* `exclusive::Bool` if `true` (the default), then like a radio
   group. Otherwise can select zero, one or more of the buttons.

## Signals

* `valueChanged (value)` when a button is toggled

## TODO

* `setItems` method

## Examples
```julia
w = window(title="buttongroup")
f = formlayout(w); push!(w, f)

ebg = buttongroup(f, ["one", "two", "three"], "one")
push!(f, ebg, "exclusive")

nebg = buttongroup(f, ["one", "two", "three"], exclusive=false)
push!(f, nebg, "non-exclusive")

b = button(f, "print values")
connect(b, :clicked, () -> println("Exclusive:", ebg[:value], "\nNon-exclusive: ", nebg[:value]))
push!(f, b, "")

```
""" ->
function buttongroup(parent::Container, model::VectorModel; exclusive::Bool=true, kwargs...)
    widget, block = buttongroup(parent.toolkit, parent, model, exclusive=exclusive)
    obj = ButtonGroup(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj.attrs[:exclusive] = exclusive
    obj
end

function buttongroup{T <: String}(parent::Container, items::Vector{T}, value=nothing;
                                  exclusive::Bool=true, kwargs...)
    if !exclusive
        if value == nothing
            value = String[]
        end
        if !isa(value, Vector) value = [value] end
    end

    model = VectorModel(items, value)
    buttongroup(parent, model, exclusive=exclusive, kwargs...)
end

## set by label
setValue{T <: String}(obj::ButtonGroup, values::Vector{T}) = (obj.model[:value] = map(string, values))

## combobox
type ComboBox <:  WidgetVectorModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Combobox

Arguments:

* `parent::Container` parent container `model::VectorModel` model
* (more conveniently items and value can be specifed). The `value`
  defaults to `items[1]`.
* `editable::Bool` if true, create editable combobox.

Signals:

* `valueChanged (value)` called when combobox is update

TODO:

* `:editable=true` (will add `editingFinished` signal

## Examples
```julia
w = window(title="combobox")
f = formlayout(w); push!(w, f)
xs = ["one", "two", "three"]

cb1 = combobox(f, xs)
push!(f, cb1, "non-editable")

cb2 = combobox(f, xs, editable=true)
push!(f, cb2, "editable")

b = button(f, "values")
push!(f, b, "")

connect(b, :clicked) do
    println("non-editable: ", cb1[:value])
    println("editable: ", cb2[:value])
end
```
""" ->
function combobox(parent::Container, model::VectorModel; editable::Bool=false, kwargs...)
    widget, block = combobox(parent.toolkit, parent, model, editable=editable)

    obj = ComboBox(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

function combobox(parent::Container, items::Vector, value=items[1]; editable::Bool=false, kwargs...)
    model = VectorModel(items, value)
    combobox(parent, model, editable=editable, kwargs...)
end

## slider
## Slider slides over indices in a sortable vector (not low to high, use linspace or range to control)
## so model has items as items to select from, value an index
type Slider <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Slider widget

Slider values are specified as a vector (not a from/to/by specification).

## Arguments:

* `model::VectorModel` a model containing value and vector information. The value is the index of the vector.
* `orientation::Sybol=:horizontal` orientation of slider when rendered
* `items::Vector` vector of items, sortable.
* `items::Range` Range of items to scroll through
* `value::Int` index of initially selected item

## Signals:

* `valueChanged (value)` return value in vector that is selected

## Notes:
use cb[:value] = nothing to deselect all

## Examples:
```julia
w = window(title="slider")
g = grid(w); push!(w, g)
slh = slider(g, 1:100, size=[200, -1])
g[1,1] = slh

slv = slider(g, 1:100, orientation=:vertical)
slv[:size] = [-1, 200]
g[1:2, 2] = slv

connect(slh, :valueChanged, value -> println(value))
""" ->
function slider(parent::Container, model::VectorModel; orientation::Symbol=:horizontal, kwargs...)
    widget, block = slider(parent.toolkit, parent, model, orientation=orientation)
    obj = Slider(widget, block, model, parent, parent.toolkit, {:orientation=>orientation})

    for (k, v) in kwargs
        obj[k] = v
    end

    obj
end
function slider(parent::Container, items::Vector, value::Int=1; orientation::Symbol=:horizontal,kwargs...)
    model = VectorModel(sort(items), value)
    slider(parent, model; orientation=orientation, kwargs...)
end
function slider(parent::Container, items::Vector; orientation::Symbol=:horizontal, kwargs...)
    items = sort(items)
    model = VectorModel(items, 1)
    slider(parent, model; orientation=orientation, kwargs...)
end

slider(parent::Container, items::Range, value::Int=1; orientation::Symbol=:horizontal, kwargs...) =
    slider(parent, [items], value; orientation=orientation, kwargs...)
slider(parent::Container, items::Range; orientation::Symbol=:horizontal, kwargs...) =
    slider(parent, [items]; orientation=orientation, kwargs...)

## slider2d
type Slider2D <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Two dimensional slider

From Mathematica's mnaipulate feature. Provides a slider for moving x and y simultaneously. Not implemented in `Gtk.jl`.

## Arguments:

* `items1` and `items2` are ranges to choose from

## Signals:

* `valueChanged (value)` is called when slider is moved. The value are [x,y] coordinates

## Examples:
```julia
if !JGUI.isgtk()
  w = window(title="2dslider")
  sl2 = slider2d(w, 1:100, 1:100)
  push!(w, sl2)
  connect(sl2, :valueChanged, value -> println(value))
end
```
""" ->
function slider2d(parent::Container, items1::Range, items2::Range; kwargs...)
    model = TwoDSliderModel([items1], [items2])
    widget, block = slider2d(parent.toolkit, parent, model)

    obj = Slider2D(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

## get and set value override
getValue(widget::Slider2D) = getValue(widget.toolkit, widget)
setValue{T<:Number}(widget::Slider2D, value::Vector{T}; signal::Bool=true) = setValue(widget.toolkit, widget, value; signal=signal)

## spinbox: integer or real
type SpinBox <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Spinbox

Widget used to collect numeric information from a specifed range

## Arguments:

* `rng` a range of type `1:10` (Range1) or `0:pi/10:pi` (Range)

## Signals:

* `valueChanged (value)` is called when spinbox is updated

## Examples:
```julia
w = window(title="spinbox")
sp = spinbox(w, 1:100)
push!(w, sp)

connect(sp, :valueChanged, value -> println(value))
```
""" ->
function spinbox(parent::Container, model::Model, rng::Range; kwargs...)
    widget, block = spinbox(parent.toolkit, parent, model, rng)
    obj = SpinBox(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj.attrs[:range] = rng
    obj
end
spinbox(parent::Container, rng::Range; kwargs...) = spinbox(parent, ItemModel(start(rng)), rng; kwargs...)

## XXX deprecate (issue with integer vs. real...)
##setRange(obj::SpinBox, value) = setRange(obj.toolkit, obj, value)
##list_props(::@PROP("SpinBox")) = {:range => "Range to select values from"}

##################################################
##
## Graphics

## CairoGraphics (for Winston)
type CairoGraphics <: WidgetModel
    o
    block
    model
    parent
    toolkit
    attrs
end

@doc """
Cairo graphics device for use with Winston graphics, say.

Not available with `Qt`.

Can be called with Winston.display(widget.o, p)

## Arguments:

## Signals:
* `mousePress (x,y)`
* `mouseRelease (x,y)`
* `mouseDoubleClick (x,y)`
* `keyPress (key)`
* `keyRelease (key)`
* `mouseMotion (x,y)`
* `mouseMove (x, y)`

The context is [x,y] in relative pixel coordinates

## TODO:

* improve interface. (Possible: `push!(cg, p)`)

## Examples:
```julia
if !JGUI.isqt()
  using Winston
  p = plot(sin, 0, 2pi);        # suppress drawing with ";"

  w = window(title="cairographic")
  cg = cairographic(w, size=[480, 400])
  push!(w, cg)
  Winston.display(cg.o, p)
end
```
""" ->
function cairographic(parent::Widget; width::Int=480, height::Int=400, kwargs...)
    model = EventModel()  # for event handling
    widget, block = cairographic(parent.toolkit, parent, model, width=width, height=height)
    obj = CairoGraphics(widget, block, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

##################################################
##
## Images

type ImageView <: Widget
    o
    block
    parent
    toolkit
    attrs
end

@doc """
Widget to display images

## Arguments:

* `img`: if specified, an image file name

Signals:

## Examples
```julia
w = window(title="image")
img = imageview(w)
push!(w, img)
if !JGUI.istk()
    ## tk does not like png files, just .gif or .jpg
    img[:image] = Pkg.dir("JGUI", "icons","default", "car.png")
end
```

""" ->
function imageview(parent::Container, img::Union(Nothing, String); kwargs...)
    widget, block = imageview(parent.toolkit, parent)
    obj = ImageView(widget, block, parent, parent.toolkit, Dict())
    if !isa(img, Nothing) obj[:image] = img end
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end
imageview(parent::Container; kwargs...) = imageview(parent, nothing; kwargs...)

function setImage(o::ImageView, img::String)
    if isfile(img)
        o.attrs[:image] = img
        setImage(o.toolkit, o, img)
    end
end
list_props(::@PROP("ImageView")) = {:image => "filename of image"}

##################################################
##
## Widgets with array or tree models

abstract ModelView <: WidgetModel
## StoreView
type StoreView <: ModelView
    o
    block
    store
    model
    parent
    toolkit
    attrs
end

@doc """

A storeview shows a set of items, where each items is displayed as a row.

## Arguments:

* `parent::Container` parent container

* `store::Store` a data store.

* `selectmode in [:single, :multiple]

## Signals:

* `selectionChanged value` (indices)
* `rowInserted, i`
* `rowRemoved, i`
* `clicked, i,j`
* `doubleClicked, i, j`
* `headerClicked, j`

## TODO: add activated signal

## Methods:

getValue returns selected items as rows
getIndex: return index (:single) or [indices] (:multiple)
setIndex: use 0 (:single) to clear, Int[] (:multiple) to clear,
getNames: return Vector{String} of names
setNames: pass `Vector{String}` of names

## Examples
```julia
## Create a store
store = Store(String, Float64)
push!(store, ("one", 1.0))
push!(store, ("two", 2.0))
push!(store, ("three", 3.0))
insert!(store, 3, ("two and a half", 2.5))

## display the store
w = window(title="storeview")
sv = storeview(w, store)
push!(w, sv)

connect(sv, :selectionChanged, indices -> println(indices)) ## failing on Gtk.selected
```

""" ->
function storeview(parent::Container, store::Store; selectmode::Symbol=:single, kwargs...)
    model = ItemModel([0])         # for selection
    widget, block = storeview(parent.toolkit, parent, store, model)
    obj = StoreView(widget, block, store, model, parent, parent.toolkit, Dict())

    ## default properties, can be overridden
    obj[:sizepolicy] = (:expand, :expand)
    obj[:selectmode] = selectmode
    obj[:rownamesvisible] = false

    for (k, v) in kwargs
        obj[k] = v
    end

    connect(store.model, "rowInserted") do row
        notify(obj.model, "rowInserted", row)
    end
    connect(store.model, "rowRemoved") do row
        notify(obj.model, "rowRemoved", row)
    end

    obj
end

getindex(s::StoreView, i::Int) = s.store.items[i]
setindex!(s::StoreView, val, i::Int) = replace!(s, i, val)

## Properties
## value is value, but should refer to things by index
function getIndex(s::StoreView)
    val = s.model[:value]
    if s[:selectmode] == :single
        length(val) == 0 && return 0
        return(val[1])
    else
        return(val)
    end
end
function setIndex(s::StoreView, index::Vector{Int})
    s.model[:value] = index
end
setIndex(s::StoreView, index::Int)  = setIndex(s, [index])
function getValue(s::StoreView)
    indices = filter(x -> x > 0, s[:index])
    items = s.store.items
    items[collect(indices)]
end
function setValue(s::StoreView, val; signal::Bool=true)
    error("Use storeview[:index] to set by row index")
end

## names
getNames(s::ModelView) = getNames(s.toolkit, s)
function setNames{T<:String}(s::StoreView, nms::Vector{T})
    @assert length(nms) == size(s.store)[2]
    setNames(s.toolkit, s, nms)
end

## is header visible? (Can't suppress in Tk)
getHeadervisible(s::StoreView) = setHeadervisible(s.toolkit, s)
setHeadervisible(s::StoreView, visible::Bool) = setHeadervisible(s.toolkit, s, visible)
getRownamesvisible(s::StoreView) = setRownamesvisible(s.toolkit, s)
setRownamesvisible(s::StoreView, visible::Bool) = setRownamesvisible(s.toolkit, s, visible)

getSelectmode(s::ModelView) = getSelectmode(s.toolkit, s)
function setSelectmode(s::ModelView, val::Symbol)
    if any(val .== [:single, :multiple])
        setSelectmode(s.toolkit, s, val)
    end
end
getWidths(s::ModelView) = getWidths(s.toolkit, s)
setWidths(s::ModelView, widths::Vector{Int}) = setWidths(s.toolkit, s, widths)
setWidths(s::ModelView, widths::Int) = setWidths(s, [widths])
getHeights(s::ModelView) = getHeights(s.toolkit, s)
setHeights(s::ModelView, heights::Vector{Int}) = setHeights(s.toolkit, s, heights)
setHeights(s::ModelView, heights::Int) = setHeights(s, [heights])

setIcon(s::StoreView, i::Int, icon::Icon) = setIcon(s.toolkit, s, i, icon)
setIcon(s::StoreView, i::Int, icon::Symbol) = setIcon(s, i, StockIcon(icon, s[:icontheme]))
setIcon(s::StoreView, i::Int, icon::String) = setIcon(s, i, FileIcon(icon))

list_props(::@PROP("ModelView")) = {:selectmode => "Either :single or :multiple",
                                    :widths => "Vector of column widths, in pixels",
                                    :heights => "Vector of row heights, in pixels"
                                    }

list_props(::@PROP("StoreView")) = {:headervisible => "Adjust if headers are displayed (if possible)",
                                    :rownamesvisible => "Adjust if rownames are displayed (if possible)",
}

## methods
insert!(s::StoreView, i::Int, val)   = insert!(s.store, i, val)
push!(s::StoreView, val)             = push!(s.store, val)
unshift!(s::StoreView, val)          = prepend!(s.store, val)
append!(s::StoreView, vals::Vector)  = append!(s.store, vals)
splice!(s::StoreView, i::Int)        = splice!(s.store, i)
pop!(s::StoreView)                   = splice!(s.store, length(s))
replace!(s::StoreView, i::Int, item) = replace!(s.store, i, item)

## list view

@doc """
Listview is a convenience wrapper to `storeview` for displaying a vector of values.

## Arguments:

* `items::Vector` items to select from

* `selectmode::Symbol` which stule of selection

## Signals:

See `storeview`.

## Properties:
`:value` return value or [value] (if :multiple)
`:index` return index or [index] (if :multiple)

## Examples
```julia
w = window(title="listview")
items = ["one", "two", "three"]
lv = listview(w, items)
push!(w, lv)
lv[:names] = ["Numbers"]
```
""" ->
function listview(parent::Container, items::Vector; selectmode::Symbol=:single, kwargs...)
    store = Store(eltype(items))
    for item in items
        push!(store, (item, ))
    end

    obj = storeview(parent, store, selectmode=selectmode)
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

##################################################
### Tree

type TreeView <: ModelView
    o
    block
    store
    model
    parent
    toolkit
    attrs
end

@doc """
treeview widget

## Arguments:

* `parent::Container` parent container

* `store::TreeStore` tree store. Most of action happens with a tree store

* `tpl` optional instance of data type for display. This allows columns to be set up in tree view. If not given, then
the store should have atleast one child node.

## Signals:

* `valueChanged (value)` Selection changes, this passes on selected path

* `activated (value)` Selection is activated, typically double click but may be enter key

* `nodeExpand (path)` gives path when node expands

* `nodeCollapsed (path)` gives path when node expands

* `clicked (path, column)` gives path and column user clicks on

* `doubleClicked(path, column)` gives path and column user clicks on

## Notes:

There are two models: one for the store where we can insert! and friends and one for the widget
where the valueChanged, nodeExpand, ... are held. These are not shared between views of the same model

## Examples
```julia
```

""" ->
function treeview(parent::Container, store::TreeStore;  kwargs...)
    model = ItemModel()
    widget, block = treeview(parent.toolkit, parent, store, model)
    obj = TreeView(widget, block, store, model, parent, parent.toolkit, Dict())
    for (k, v) in kwargs
        obj[k] = v
    end
    obj
end

## properties
## XXX no way to set column of keys...
function setNames{T<:String}(s::TreeView, nms::Vector{T})
    @assert length(nms) == length(s.store.types)
    setNames(s.toolkit, s, nms)
end

getKeyname(tr::TreeView) = getKeyname(tr.toolkit, tr)
setKeyname(tr::TreeView, nm::String) = setKeyname(tr.toolkit, tr, nm)

getKeywidth(tr::TreeView) = getKeywidth(tr.toolkit, tr)
setKeywidth(tr::TreeView, width::Int) = setKeywidth(tr.toolkit, tr, width)
list_props(::@PROP("TreeView")) = {:keyname => "Name of column holding keys",
                                   :keywidth => "Width in pixels of column holding keys"
                                 }

setIcon(s::TreeView, path::Vector{Int}, icon::Icon) = setIcon(s.toolkit, s, path, icon)
setIcon(s::TreeView, path::Vector{Int}, icon::Symbol) = setIcon(s, path, StockIcon(icon, s[:icontheme]))
setIcon(s::TreeView, path::Vector{Int}, icon::String) = setIcon(s, path, FileIcon(icon))

## expand the node is a view property, not model
expand_node(view::TreeView, node::TreeNode) = notify(view.model, "expandNode", node)
collapse_node(view::TreeView, node::TreeNode) = notify(view.model, "collapseNode", node)

## svg device

## html device

## XXX document main methods with objects
## XXX add destroy method for windows
## XXX add destroy handler
## XXX push!(child) shortcut to push!(child.parent, child)
## XXX delete! not splice!


text:
# assume ix = 1 and incx = 1

calc(::BM_TEST, ::FUNT, x, y, v) = calc(BM_JBase1(), FUNT(), x, y, v)
calc(::BM_JBase1, ::FUNT, x, y, v) = begin
    #scale!(reshape(x,(1,length(x))),y)
    copy!(x, y)
end
calc(::BM_JBase2, ::FUNT, x, y, v) = begin
    copy!(x, y)
    #scale!(v, x)
end
calc(::BM_BLAS, ::FUNT, x, y, v) = begin
    n = length(x)
    BLAS.axpy!(n, v, y, 1, x, 1)
end
calc(::BM_Broadcast, ::FUNT, x, y, v) = broadcast!(xpyv, x, x, y, v)
xpyv(x,y,v) = x + v*y
calc(::BM_Forloop, ::FUNT, x, y, v) = addarrloop1(x, y, v)
function addarrloop1(x::Array, y::Array, v)
    @inbounds for i=1:length(x)
        x[i] += v*y[i]
    end
    return x
end
calc(::BM_FAO, ::FUNT, x, y, v) = unsafe_fast_addscal!(x, 1, y, v, length(x))

Base.start{T}(p::BenchCase{T,FUNT}, n::Int) =
    (rand(n), rand(n), convert(Float64,1+1e-8))

function Base.run{Op,FUNT}(p::BenchCase{Op,FUNT}, n::Int, s)  # bench type, config, start value
    calc(Op(), FUNT(), s...)
    return nothing
end


text:
ActivationContributionLow(l) = ActivationContribution(l, NeuronUtilityEvery(20))

default_layerconf() = LayerVertexConf(ActivationContributionLow ∘ LazyMutable, NaiveGAflux.default_logging())
# Global pool has its own config because it happens to not be compatible with LazyMutable. Should be fixed someday
default_globpoolconf() = LayerVertexConf(ActivationContributionLow, MutationShield ∘ NaiveGAflux.default_logging())

default_actfuns() = [identity, Flux.relu, Flux.elu, Flux.selu]
function initial_archspace(inshape, outsize)

    layerconf = default_layerconf()
    gpconf = default_globpoolconf()
    outconf = let OutShield(t) = MutationShield(t, KernelSizeMutation, ActivationFunctionMutation)
        LayerVertexConf(layerconf.layerfun, OutShield ∘ layerconf.traitfun)
    end

    acts = default_actfuns()

    # Only use odd kernel sizes due to CuArrays issue# 356
    # Bias selection towards smaller number of large kernels in the beginning...
    conv1 = convspace(layerconf, 2 .^(3:8), 1:2:7, acts)
    # Then larger number of small kernels
    conv2 = convspace(layerconf, 2 .^(5:9), 1:2:5, acts)

    # Convblocks are repeated, forked or put in residual connections.
    rfr1 = rep_fork_res(conv1, 1)
    rfr2 = rep_fork_res(conv2, 1)

    # Each "block" is finished with downsampling
    red1 = ArchSpaceChain(rfr1, downsamplingspace(layerconf, outsizes=2 .^(3:8), activations=acts))
    red2 = ArchSpaceChain(rfr2, downsamplingspace(layerconf, outsizes=2 .^(5:9), activations=acts))

    # How many times can shape be reduced by a factor 2
    maxreps = min(6, floor(Int, log2(minimum(inshape))))
    # Block 1 (large kernels and small sizes) repeated up to 2 times
    block1 = RepeatArchSpace(red1, 1:maxreps ÷ 2)
    # And the same for block type 2
    block2 = RepeatArchSpace(red2, 1:maxreps ÷ 2)

    # Ok, lets work on the output layers.
    # Two main options:

    # Option 1: Just a global pooling layer
    # For this to work we need to ensure that the layer before the global pool has exactly 10 outputs, that is what this is all about (or else we could just have allowed 0 dense layers in the search space for option 2).
    convout = convspace(outconf, outsize, 1:2:5, identity)
    blockcout = ArchSpaceChain(convout, GlobalPoolSpace(gpconf))

    # Option 2: 1-3 Dense layers after the global pool
    dense = VertexSpace(layerconf, NamedLayerSpace("dense", DenseSpace(2 .^(8:12), acts)))
    drep = RepeatArchSpace(dense, 0:2)
    dout=VertexSpace(outconf, NamedLayerSpace("dense", DenseSpace(outsize, identity)))
    blockdout = ArchSpaceChain(GlobalPoolSpace(gpconf), drep, dout)

    blockout = ArchSpace(blockdout, blockcout)

    # Remember that each "block" here is a random and pretty big search space.
    # Basically the only constraint is to not randomly run out of GPU memory...
    return ArchSpaceChain(block1, block2, blockout)
end

function rep_fork_res(s, n, min_rp=1;loglevel=Logging.Debug)
    n == 0 && return s

    resconf = VertexConf(outwrap = ActivationContributionLow, traitdecoration = MutationShield ∘ NaiveGAflux.default_logging())
    concconf = ConcConf(ActivationContributionLow,  MutationShield ∘ NaiveGAflux.default_logging())

    msgfun(v) = "Created $(name(v)), nin: $(nin(v)), nout: $(nout(v))"

    rep = RepeatArchSpace(s, min_rp:2) # Does not need logging as layers log themselves
    fork = LoggingArchSpace(msgfun, ForkArchSpace(rep, min_rp:3, conf=concconf); level = loglevel)
    res = LoggingArchSpace(msgfun, ResidualArchSpace(rep, resconf); level = loglevel)
    # Manical cackling laughter...
    return rep_fork_res(ArchSpace(rep, fork, res), n-1, 0, loglevel=loglevel)
end

function convspace(conf, outsizes, kernelsizes, acts; loglevel=Logging.Debug)
    msgfun(v) = "Created $(name(v)), nin: $(nin(v)), nout: $(nout(v))"
    aswrap(vname, as) = LoggingArchSpace(msgfun, VertexSpace(conf, NamedLayerSpace(vname, as)); level=loglevel)

    conv2d = aswrap("conv2d", ConvSpace{2}(outsizes=outsizes, activations=acts, kernelsizes=kernelsizes))
    bn = aswrap("batchnorm", BatchNormSpace(acts))

    # Make sure that each alternative has the option to change output size
    # This is important to make fork and res play nice together
    convbn = ArchSpaceChain(conv2d, bn)
    bnconv = ArchSpaceChain(bn, conv2d)

    return ArchSpace(ParSpace([conv2d, convbn, bnconv]))
end

function downsamplingspace(conf; outsizes, sizes=2, strides=2, activations=identity)
    maxpoolspace = NamedLayerSpace("maxpool", PoolSpace{2}(windowsizes=sizes, strides=strides, poolfuns=MaxPool))
    meanpoolspace = NamedLayerSpace("meanpool", PoolSpace{2}(windowsizes=sizes, strides=strides, poolfuns=MeanPool))
    convspace = NamedLayerSpace("stridedconv", ConvSpace{2}(outsizes=outsizes, kernelsizes=sizes, activations=activations, strides=strides, paddings=0))
    return ArchSpace(maxpoolspace, meanpoolspace, convspace; conf=conf)
end


text:
# https://juliagraphics.github.io/Gtk.jl/latest/manual/combobox/#GtkComboBoxText-1
# The following example shows how to fill a GtkComboBoxText with elements and
# listen on the changed event

using Gtk

cb = GtkComboBoxText()
choices = ["one", "two", "three", "four"]
for choice in choices
  push!(cb,choice)
end
# Lets set the active element to be "two"
set_gtk_property!(cb,:active,1)

signal_connect(cb, "changed") do widget, others...
  # get the active index
  idx = get_gtk_property(cb, "active", Int)
  # get the active string
  # We need to wrap the GAccessor call into a Gtk bytestring
  str = Gtk.bytestring( GAccessor.active_text(cb) )
  println("Active element is \"$str\" at index $idx")
end

win = GtkWindow("ComboBoxText Example",400,200)
push!(win, cb)
showall(win)


text:
using Docile.Interface

facts("Filtering.") do

    context("Filter.") do

        d = metadata(Docile);

        # Filter entries with categories of :macro and :type
        d1 = filter(d, categories = [:macro])

        res = [category(v) for (k,v) in EachEntry(d1)]
        @fact all(res .== :macro) --> true

        d2 = filter(d) do e
            category(e) == :type
        end
        @fact all([category(v) == :type for (k,v) in EachEntry(d2)]) --> true

    end

    context("EachEntry.") do

        d = metadata(Docile);

        res = [v.data[:source][1] for (k,v) in EachEntry(filter(d, files = ["types.jl"]), order = [:source])]
        @fact issorted(res) --> true

    end

end