package plist

import (
<<<<<<< HEAD
	"github.com/emirpasic/gods/trees/avltree"
=======
	"log"

>>>>>>> 86a8ee11986ed2002b8beb5420349f350594efd7
	"github.com/emirpasic/gods/utils"
)

// PriorityQueue 优先队列 适合数据量不大, 加索引
type PriorityQueue struct {
<<<<<<< HEAD
	avl        *avltree.Tree
	size       int
	comparator utils.Comparator
	splitlimit int
}

func NewWithIntComparator() *PriorityQueue {
	pq := new(PriorityQueue)
	pq.comparator = func(v1, v2 interface{}) int {
		if v1.(int) > v2.(int) {
=======
	data *Tree

	Head       *AvlNode
	Tail       *AvlNode
	comparator utils.Comparator
}

// NewWithInt compare use int
func NewWithInt() *PriorityQueue {
	p := new(PriorityQueue)

	p.comparator = func(a, b interface{}) int {

		if a.(int) == b.(int) {
			return 0
		}

		if a.(int) > b.(int) {
>>>>>>> 86a8ee11986ed2002b8beb5420349f350594efd7
			return 1
		} else if v1.(int) < v2.(int) {
			return -1
		}
<<<<<<< HEAD
		return 0
	}
	pq.avl = avltree.NewWith(pq.comparator)
	pq.size = 0
	return pq
}

func (pq *PriorityQueue) Push(value interface{}) {
	var pl *PriorityList
	pq.size++

	floor, ok := pq.avl.Floor(value)
	if ok {

		pl = floor.Value.(*PriorityList)
		cur := pl.head
		pl.size++

		if pq.comparator(value, cur.value) > 0 {

			temp := pl.head
			pl.head = &Node{value: value}
			pl.head.next = temp

			return
		}

		for cur.next != nil {
			if pq.comparator(value, cur.next.value) >= 0 {
				temp := cur.next
				cur.next = &Node{value: value}
				cur.next.next = temp
				return
			}
			cur = cur.next
		}
		// next == nil
		cur.next = &Node{value: value}
		return

	}

	pl = &PriorityList{}
	pl.head = &Node{value: value}
	pl.size++

	pq.avl.Put(pl.head.value, pl)

	return

=======

		return -1
	}

	p.data = NewWith(p.comparator)

	return p
}

func (pq *PriorityQueue) String() string {
	return pq.data.String()
}

func (pq *PriorityQueue) Top() (interface{}, bool) {
	return pq.Head, pq.Head != nil
}

func (pq *PriorityQueue) Bottom() (interface{}, bool) {
	return pq.Tail, pq.Tail != nil
}

func (pq *PriorityQueue) Get(index int) (interface{}, bool) {
	var cur *AvlNode
	if index >= 0 {
		cur = pq.Head
		for index > 0 && cur != nil {
			index--
			cur = cur.Prev()
		}
	} else {
		cur = pq.Tail
		for index < -1 && cur != nil {
			index++
			cur = cur.Next()
		}
	}
	return cur.Value, cur != nil
}

// GetNode unsafe 破坏AvlNode属性会破坏整个数据结构
func (pq *PriorityQueue) GetNode(index int) (*AvlNode, bool) {
	var cur *AvlNode
	if index >= 0 {
		cur = pq.Head
		for index > 0 && cur != nil {
			index--
			cur = cur.Prev()
		}
	} else {
		cur = pq.Tail
		for index < -1 && cur != nil {
			index++
			cur = cur.Next()
		}
	}

	return cur, cur != nil
}

func (pq *PriorityQueue) Push(v interface{}) {

	pnode := pq.data.Put(v)
	if pq.Head == nil {
		pq.Head = pnode
		pq.Tail = pnode
		return
	}

	if pq.comparator(v, pq.Head.Value) > 0 {
		pq.Head = pnode
		return
	}

	if pq.comparator(v, pq.Tail.Value) < 0 {
		pq.Tail = pnode
		return
	}
}

func (pq *PriorityQueue) RemoveNode(node *AvlNode) {
	if node == pq.Head {
		pq.Head = node.Prev()
	}

	if node == pq.Tail {
		pq.Tail = node.Next()
	}

	pq.data.remove(node.Value, &node)
}

func (pq *PriorityQueue) Remove(index int) *AvlNode {

	node, ok := pq.GetNode(index)
	if ok {
		if node == pq.Head {
			pq.Head = node.Prev()
		}

		if node == pq.Tail {
			pq.Tail = node.Next()
		}

		next := node.Prev()
		log.Println(next, next.Next())
		pq.data.remove(node.Value, &next)
		return node
	}
	return nil
}

func (pq *PriorityQueue) Values() []interface{} {
	return pq.data.Values()
>>>>>>> 86a8ee11986ed2002b8beb5420349f350594efd7
}
