text: // +build windows
  // Copyright 2013, Örjan Persson. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package logging
  
  import (
  	"bytes"
  	"io"
  	"log"
  	"syscall"
  )
  
  var (
  	kernel32DLL                 = syscall.NewLazyDLL("kernel32.dll")
  	setConsoleTextAttributeProc = kernel32DLL.NewProc("SetConsoleTextAttribute")
  )
  
  // Character attributes
  // Note:
  // -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).
  //    Clearing all foreground or background colors results in black; setting all creates white.
  // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
  const (
  	fgBlack     = 0x0000
  	fgBlue      = 0x0001
  	fgGreen     = 0x0002
  	fgCyan      = 0x0003
  	fgRed       = 0x0004
  	fgMagenta   = 0x0005
  	fgYellow    = 0x0006
  	fgWhite     = 0x0007
  	fgIntensity = 0x0008
  	fgMask      = 0x000F
  )
  
  var (
  	colors = []uint16{
  		INFO:     fgWhite,
  		CRITICAL: fgMagenta,
  		ERROR:    fgRed,
  		WARNING:  fgYellow,
  		NOTICE:   fgGreen,
  		DEBUG:    fgCyan,
  	}
  	boldcolors = []uint16{
  		INFO:     fgWhite | fgIntensity,
  		CRITICAL: fgMagenta | fgIntensity,
  		ERROR:    fgRed | fgIntensity,
  		WARNING:  fgYellow | fgIntensity,
  		NOTICE:   fgGreen | fgIntensity,
  		DEBUG:    fgCyan | fgIntensity,
  	}
  )
  
  type file interface {
  	Fd() uintptr
  }
  
  // LogBackend utilizes the standard log module.
  type LogBackend struct {
  	Logger *log.Logger
  	Color  bool
  
  	// f is set to a non-nil value if the underlying writer which logs writes to
  	// implements the file interface. This makes us able to colorise the output.
  	f file
  }
  
  // NewLogBackend creates a new LogBackend.
  func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend {
  	b := &LogBackend{Logger: log.New(out, prefix, flag)}
  
  	// Unfortunately, the API used only takes an io.Writer where the Windows API
  	// need the actual fd to change colors.
  	if f, ok := out.(file); ok {
  		b.f = f
  	}
  
  	return b
  }
  
  func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error {
  	if b.Color && b.f != nil {
  		buf := &bytes.Buffer{}
  		setConsoleTextAttribute(b.f, colors[level])
  		buf.Write([]byte(rec.Formatted(calldepth + 1)))
  		err := b.Logger.Output(calldepth+2, buf.String())
  		setConsoleTextAttribute(b.f, fgWhite)
  		return err
  	}
  	return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1))
  }
  
  // setConsoleTextAttribute sets the attributes of characters written to the
  // console screen buffer by the WriteFile or WriteConsole function.
  // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
  func setConsoleTextAttribute(f file, attribute uint16) bool {
  	ok, _, _ := setConsoleTextAttributeProc.Call(f.Fd(), uintptr(attribute), 0)
  	return ok != 0
  }
  
  func doFmtVerbLevelColor(layout string, level Level, output io.Writer) {
  	// TODO not supported on Windows since the io.Writer here is actually a
  	// bytes.Buffer.
  }
  