//
// Copyright 2003, Juan Segarra Flor
//
// This is part of videocache
//
// Videocache is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Videocache is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Foobar; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include <stdlib.h>
#include <iostream>
#include <math.h>
#include <string.h>
#include "config.h"

extern long partstransmittedpp; //parts transmitted from point to point
extern long partsmulticastpp;  // parts transmitted without bw cost pp
extern long *linktraffic; // array storing the traffic in each link

/* table element: timeslot with a link array */
typedef struct timeslot{
  struct timeslot* next;
  int slot;
  long* link;
  long* userlink;
} t_timeslot;

/* element of planned transmission */
typedef struct plan{
  struct plan* next;
  //int video;       //next plan
  int part;      // video part
  int start;     // start slot
  int *linklist;    // array of links reserved links, ended with -1
  int duration;  // duration slots
  long bw;       // cbr bandwidth
  struct plan* prev; //previous plan
  long *idlist;  // array of user ids, ended with -2 (-1 = realloc)
} t_plan;
  
/* table class */
class bwtable {
  int maxlinks; // total links
  int maxvideos; // total videos
  long maxusers; // total users
  int actualslot; // 1+slot of simulation time;
  // all slots must be higher than actualslot
  // plans are deleted when start+duration > actualslot
  t_timeslot* first; // first element
  long* capacity;  // link capacity
  long *usercapacity;    // user links capacity
  t_plan** planlistbyvid;  // array of plans by video

  long* seekslot(int numslot);
  long* seekuserslot(int numslot);
  int testslot(long bw,int numslot,int numlink);
  int testuserslot(long bw,int numslot,long numuser);
  int reserveslot(long bw,int numslot,int numlink);
  int reserveuserslot(long bw,int numslot,long numuser);
  int unreserveslot(long bw,int numslot,int numlink);
  int unreserveuserslot(long bw,int numslot,long numuser);
  int addplan(int video,int part,int startslot,int* linklist,
	      int duration,long bw,long id);
  // addplan does NOT include the link bandwidth sum (reserveslot)
  int addmulticastplan(int mylink,long myid,t_plan *plan);
  int removelink(int link,t_plan* plan);
  int removeid(long id,t_plan* plan);
  int addid(long id,t_plan* plan);
  int delplan(t_plan *aux,int videolist);
  // delplan does NOT include the link bandwidth substraction (unreserveslot)
  int unreserveplan(int video,t_plan *auxplan);
  int isinlinks(int mylink,t_plan *plan);
  int isinids(long myid,t_plan *plan);
  t_plan* seekplan(int video,int part,int startslot,
		   long strictflag,int*linklist);
  t_plan* seekplantoremove(int video,int part,long user);
  int adjusttransmplan(int video,int numslot);
  long getplannedbwfromslot(int numslot);
  long getvideoplannedbwfromslot(int videoid,int numslot);
  //t_plan* getplanbytime(int video,int numslot);
  int* getbwusage(int video,int link,int numslot);
  t_timeslot* getmostsaturatedslot(long numlink,int video,long id);
  t_plan* getplanbylinkusage(long numlink,int video,long id,long maxbw);
  t_plan* getplanbytime(int video,int numslot);
  t_plan* getplanbyinvtime(int video,int numslot);
  int adjustthisplan(int video,t_plan *plan,int numslot);
 public:
  bwtable(int numlinks,long linkcapacity,int numvideos,
	  long numusers,long userlinkcapacity); //constructor
  int delslotsto(int numslot); // frees reached timeslots
  int testroute(int video,int part,long bw,int startslot,
		int duration,int* linklist,long id);
  // test if we can reserve $bw$ in that links at that slots
  int reserveroute(int video,int part,long bw,int startslot,
		   int duration,int *linklist,long id);
  // reserves $bw$ in that links at that slots
  int unreserveroute(int video,int part,long bw,int startslot,
		     int duration,int* linklist,long id);
  //int getfirsttranstime(int video);
  // returns a timeslot to start transmitting
  long getlinkcapacity(int link);
  // returns the link capacity
  int adjustthisslot(int numslot);
  // dynamic slot adjusting: fill links and modify reservations
  void setactualslot(int numslot){actualslot=numslot;};
};
