/*## (c) SECURITY EXPLORATIONS    2018 poland                                #*/
/*##     http://www.security-explorations.com                                #*/

/* THIS SOFTWARE IS PROTECTED BY DOMESTIC AND INTERNATIONAL COPYRIGHT LAWS    */
/* UNAUTHORISED COPYING OF THIS SOFTWARE IN EITHER SOURCE OR BINARY FORM IS   */
/* EXPRESSLY FORBIDDEN. ANY USE, INCLUDING THE REPRODUCTION, MODIFICATION,    */
/* DISTRIBUTION, TRANSMISSION, RE-PUBLICATION, STORAGE OR DISPLAY OF ANY      */
/* PART OF THE SOFTWARE, FOR COMMERCIAL OR ANY OTHER PURPOSES REQUIRES A      */
/* VALID LICENSE FROM THE COPYRIGHT HOLDER.                                   */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS    */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/
/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    */
/* SECURITY EXPLORATIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF  */
/* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE     */
/* SOFTWARE.                                                                  */

import java.lang.*;
import java.util.*;
import java.text.*;
import javax.tv.service.*;
import javax.tv.service.guide.*;
import javax.tv.service.navigation.*;

public class EPG {
 public static final int PAD  = 35;

 public static class ProgramEventRequestor implements SIRequestor {
  public void notifyFailure(SIRequestFailureType reason) {
   synchronized(pe_syncobj) {
    pe_syncobj.notify();
   }
  }

  public void notifySuccess(SIRetrievable[] result) {
   try {
    synchronized(pe_syncobj) {
     pe=(ProgramEvent)result[0];

     pe_syncobj.notify();
    }
   } catch(Throwable e) {
   }
  }
 }

 private static ProgramEvent pe;
 private static Object pe_syncobj=new Object();

 public static ProgramSchedule get_program_schedule(Service srv) {
  ProgramSchedule ps=null;

  ServiceDetails sd=SrvUtils.get_service_details(srv);

  if (sd!=null) {
   ps=sd.getProgramSchedule();
  }

  return ps;
 }

 public static ProgramEvent get_current_event(Service srv) {
  pe=null;

  try {
   ProgramSchedule ps=get_program_schedule(srv);

   if (ps!=null) {
    synchronized(pe_syncobj) {
     ps.retrieveCurrentProgramEvent(new ProgramEventRequestor());
     pe_syncobj.wait();
    }
   }

  } catch(Throwable t) {}

  return pe;
 }

 public static ProgramEvent[] get_events(Service srv,int cnt) {
  Vector v=new Vector();

  try {
   ProgramSchedule ps=get_program_schedule(srv);
   ProgramEvent event=get_current_event(srv);

   if (event!=null) {
    v.addElement(event);
    cnt--;

    while(cnt>0) {
     pe=null;

     synchronized(pe_syncobj) {
      ps.retrieveNextProgramEvent(event,new ProgramEventRequestor());
      pe_syncobj.wait();
     }

     if (pe!=null) {
      v.addElement(pe);
      cnt--;

      event=pe;
     } else break;
    }
   }

  } catch(Throwable t) {}

  ProgramEvent evtab[]=new ProgramEvent[v.size()];

  for(int i=0;i<v.size();i++) {
   evtab[i]=(ProgramEvent)v.elementAt(i);
  }

  return evtab;
 }

 public static void print_event(ProgramEvent pe) throws Throwable {
  SimpleDateFormat df=new SimpleDateFormat("HH:mm");

  Date start=pe.getStartTime();
  Date end=pe.getEndTime();
  String name=pe.getName();

  String s="["+df.format(start)+"-"+df.format(end)+"] "+name;

  Output.text(s);
 }

 public static void print_events(Service srv,int cnt) throws Throwable {
  ProgramEvent evtab[]=get_events(srv,cnt);

  if (evtab!=null) {
   int num=SrvUtils.channel_by_srv(srv);

   String s=" "+Utils.padded_int(num,4)+"  \""+srv.getName()+"\"  "+srv.getLocator();
   Output.text(s);

   for(int i=0;i<evtab.length;i++) {
    print_event(evtab[i]);
   }
  }
 }

}
