package cview

import (
	

	
)

// Window is a draggable, resizable frame around a primitive. Windows must be
// added to a WindowManager.
type Window struct {
	*Box

	primitive Primitive

	fullscreen bool

	normalX, normalY int
	normalW, normalH int

	dragX, dragY   int
	dragWX, dragWY int

	sync.RWMutex
}

// NewWindow returns a new window around the given primitive.
func ( Primitive) *Window {
	 := &Window{
		Box:       NewBox(),
		primitive: ,
		dragWX:    -1,
		dragWY:    -1,
	}
	.Box.focus = 
	return 
}

// SetFullscreen sets the flag indicating whether or not the the window should
// be drawn fullscreen.
func ( *Window) ( bool) {
	.Lock()
	defer .Unlock()

	if .fullscreen ==  {
		return
	}

	.fullscreen = 
	if .fullscreen {
		.normalX, .normalY, .normalW, .normalH = .GetRect()
	} else {
		.SetRect(.normalX, .normalY, .normalW, .normalH)
	}
}

// Focus is called when this primitive receives focus.
func ( *Window) ( func( Primitive)) {
	.Lock()
	defer .Unlock()

	.Box.Focus()

	.primitive.Focus()
}

// Blur is called when this primitive loses focus.
func ( *Window) () {
	.Lock()
	defer .Unlock()

	.Box.Blur()

	.primitive.Blur()
}

// HasFocus returns whether or not this primitive has focus.
func ( *Window) () bool {
	.RLock()
	defer .RUnlock()

	 := .primitive.GetFocusable()
	if  != nil {
		return .HasFocus()
	}

	return .Box.HasFocus()
}

// Draw draws this primitive onto the screen.
func ( *Window) ( tcell.Screen) {
	if !.GetVisible() {
		return
	}

	.RLock()
	defer .RUnlock()

	.Box.Draw()

	, , ,  := .GetInnerRect()
	.primitive.SetRect(, , , )
	.primitive.Draw()
}

// InputHandler returns the handler for this primitive.
func ( *Window) () func( *tcell.EventKey,  func( Primitive)) {
	return .primitive.InputHandler()
}

// MouseHandler returns the mouse handler for this primitive.
func ( *Window) () func( MouseAction,  *tcell.EventMouse,  func( Primitive)) ( bool,  Primitive) {
	return .WrapMouseHandler(func( MouseAction,  *tcell.EventMouse,  func( Primitive)) ( bool,  Primitive) {
		if !.InRect(.Position()) {
			return false, nil
		}

		if  == MouseLeftDown ||  == MouseMiddleDown ||  == MouseRightDown {
			()
		}

		if  == MouseLeftDown {
			, , ,  := .GetRect()
			,  := .Position()

			 :=  == 
			 :=  == +-1
			 :=  == +-1
			 :=  == 

			if  >=  &&  <= +-1 {
				if  {
					.dragX = -1
				} else if  {
					.dragX = 1
				}
			}

			if  >=  &&  <= +-1 {
				if  {
					.dragY = -1
				} else if  {
					if  ||  {
						.dragY = 1
					} else {
						.dragWX =  - 
						.dragWY =  - 
					}
				}
			}
		}

		_,  = .primitive.MouseHandler()(, , )
		return true, 
	})
}