// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package lifecycle defines an event for an app's lifecycle.
//
// The app lifecycle consists of moving back and forth between an ordered
// sequence of stages. For example, being at a stage greater than or equal to
// StageVisible means that the app is visible on the screen.
//
// A lifecycle event is a change from one stage to another, which crosses every
// intermediate stage. For example, changing from StageAlive to StageFocused
// implicitly crosses StageVisible.
//
// Crosses can be in a positive or negative direction. A positive crossing of
// StageFocused means that the app has gained the focus. A negative crossing
// means it has lost the focus.
//
// See the golang.org/x/mobile/app package for details on the event model.
package lifecycle // import "golang.org/x/mobile/event/lifecycle"

import (
	"fmt"
)

// Cross is whether a lifecycle stage was crossed.
type Cross uint32

func (c Cross) String() string {
	switch c {
	case CrossOn:
		return "on"
	case CrossOff:
		return "off"
	}
	return "none"
}

const (
	CrossNone Cross = 0
	CrossOn   Cross = 1
	CrossOff  Cross = 2
)

// Event is a lifecycle change from an old stage to a new stage.
type Event struct {
	From, To Stage

	// DrawContext is the state used for painting, if any is valid.
	//
	// For OpenGL apps, a non-nil DrawContext is a gl.Context.
	//
	// TODO: make this an App method if we move away from an event channel?
	DrawContext interface{}
}

func (e Event) String() string {
	return fmt.Sprintf("lifecycle.Event{From:%v, To:%v, DrawContext:%v}", e.From, e.To, e.DrawContext)
}

// Crosses reports whether the transition from From to To crosses the stage s:
//   - It returns CrossOn if it does, and the lifecycle change is positive.
//   - It returns CrossOff if it does, and the lifecycle change is negative.
//   - Otherwise, it returns CrossNone.
//
// See the documentation for Stage for more discussion of positive and negative
// crosses.
func (e Event) Crosses(s Stage) Cross {
	switch {
	case e.From < s && e.To >= s:
		return CrossOn
	case e.From >= s && e.To < s:
		return CrossOff
	}
	return CrossNone
}

// Stage is a stage in the app's lifecycle. The values are ordered, so that a
// lifecycle change from stage From to stage To implicitly crosses every stage
// in the range (min, max], exclusive on the low end and inclusive on the high
// end, where min is the minimum of From and To, and max is the maximum.
//
// The documentation for individual stages talk about positive and negative
// crosses. A positive lifecycle change is one where its From stage is less
// than its To stage. Similarly, a negative lifecycle change is one where From
// is greater than To. Thus, a positive lifecycle change crosses every stage in
// the range (From, To] in increasing order, and a negative lifecycle change
// crosses every stage in the range (To, From] in decreasing order.
type Stage uint32

// TODO: how does iOS map to these stages? What do cross-platform mobile
// abstractions do?

const (
	// StageDead is the zero stage. No lifecycle change crosses this stage,
	// but:
	//	- A positive change from this stage is the very first lifecycle change.
	//	- A negative change to this stage is the very last lifecycle change.
	StageDead Stage = iota

	// StageAlive means that the app is alive.
	//	- A positive cross means that the app has been created.
	//	- A negative cross means that the app is being destroyed.
	// Each cross, either from or to StageDead, will occur only once.
	// On Android, these correspond to onCreate and onDestroy.
	StageAlive

	// StageVisible means that the app window is visible.
	//	- A positive cross means that the app window has become visible.
	//	- A negative cross means that the app window has become invisible.
	// On Android, these correspond to onStart and onStop.
	// On Desktop, an app window can become invisible if e.g. it is minimized,
	// unmapped, or not on a visible workspace.
	StageVisible

	// StageFocused means that the app window has the focus.
	//	- A positive cross means that the app window has gained the focus.
	//	- A negative cross means that the app window has lost the focus.
	// On Android, these correspond to onResume and onFreeze.
	StageFocused
)

func (s Stage) String() string {
	switch s {
	case StageDead:
		return "StageDead"
	case StageAlive:
		return "StageAlive"
	case StageVisible:
		return "StageVisible"
	case StageFocused:
		return "StageFocused"
	default:
		return fmt.Sprintf("lifecycle.Stage(%d)", s)
	}
}
