use std::collections::HashMap;
use std::cmp::Ordering;
use std::cmp::min;

#[derive(Debug)]
struct Offer {
  sell_qty: u64,
  sell_remain: u64,
  sell_per_buy: u64,	// Order heaps on this, decreasing order (highest on top)
  buy_royalty_acc: u64,
  buy_royalty_cap: u64,
  }

struct Market {
  offers: HashMap<(String,String),PQueue<Offer>>,
  }

impl Market {
    fn new() -> Self {
        Market {
            offers: HashMap::new()
            }
        }
    fn MakeOffer(&mut self, sell_type:String, buy_type:String, sell_qty:u64, sell_per_buy:u64)
      {
      let mut sell_qty=sell_qty;
//      let bp=(sell_type.clone(),buy_type.clone());
      let ap=(buy_type,sell_type);
//      let bids=&self.offers[&bp];
      let asks=&self.offers[&ap];
//      let mut topask=asks.peek();
//      while asks.peek().sell_per_buy<sell_per_buy
//        {
//        let topask=asks.peek();
//        let transact=min(sell_qty,topask.sell_remain);
//        topask.sell_remain-=transact;
//        sell_qty-=transact;
//        }
      }
    }


impl PartialOrd for Offer {
    fn partial_cmp(&self, other:&Self) -> Option<Ordering> {
        if      self.sell_per_buy<other.sell_per_buy { Some(Ordering::Less) }
        else if self.sell_per_buy>other.sell_per_buy { Some(Ordering::Greater) }
        else                                         { Some(Ordering::Equal) }
        }
    }

impl PartialEq for Offer {
    fn eq(&self, other:&Self) -> bool {
        self.sell_per_buy==other.sell_per_buy
        }
    }

struct PQueue<T> {
  v: Vec<T>,
  }

impl<T: std::cmp::PartialOrd + std::fmt::Debug> PQueue<T> {
    fn new()->Self {
        PQueue {
            v: Vec::new()
            }
        }
    fn peek(&self) -> T {
        self.v[0]
        }
    fn bubble_up(&mut self, pos: usize) {
        if pos>0 {
	    let parent=(pos-1)/2;
            if self.v[parent]<self.v[pos] {
	        self.v.swap(parent,pos);
		self.bubble_up(parent);
                }
	    }
        }
    fn trickle_down(&mut self, pos: usize) {
        let mut pivot=pos;
        let child0=pos*2+1;
	let child1=pos*2+2;
	if child0<self.v.len() {
	    if self.v[pos]<self.v[child0] { pivot=child0; }
	    if child1<self.v.len() {
	        if self.v[pivot]<self.v[child1] { pivot=child1; }
	        }
	    if pivot!=pos {
	        self.v.swap(pivot,pos);
		self.trickle_down(pivot);
		}
            }
        }
    fn insert(&mut self, item: T) {
        self.v.push(item);
        self.bubble_up(self.v.len()-1);
        }
    fn pop(&mut self) -> Option<T> {
        if self.v.len()==0 { None }
        else {
            let end=self.v.len()-1;
            self.v.swap(0,end);
            let rval=self.v.pop();
            self.trickle_down(0);
            rval
            }
        }
    fn dump(&self) {
        println!("PQueue length {}:",self.v.len());
        for index in 0..self.v.len() { println!("{:?}",self.v[index]); }
        }
    }




fn main() {
  let mut m=Market::new();
  let mut pq:PQueue<Offer>=PQueue::new();
  pq.dump();
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
  println!("{:?}",pq.pop());
}
