###############################################################################
# Copyright (c) 2012 Trimble Navigation Ltd
# $Id: NoPiSD_Web_Page.py,v 1.3 2012/08/30 19:14:35 shankar Exp $
###############################################################################
#
# NoPiSD_Web_Page.py
#
# Class contains all the functions needed to generate long term trends web page
#
# The webpage consists of three separete html pages: A top-level
# file, a results frame and a menu frame, each stored as a html page
#
# The web page contains JavaScript functions that are imported from a
# separate .js file and included in the top-level web page
#
###############################################################################

import os
import datetime

from NoPiSD_Utils import add_utils_dir_to_path
add_utils_dir_to_path()

from NoPiUT_Common_Display import *
from NoPiUT_Common_Meas import str2obj_date
from NoPiSD_Plot import get_combo_short_name

###############################################################################
# Create output web directory
###############################################################################

if ( not( os.access( 'web', os.F_OK ) ) ) :
  print 'Create web directory'
  os.mkdir( 'web' )

###############################################################################
# Class of functions used to generate the long term trends web page
###############################################################################

class cl_web_page : 

  #############################################################################
  # Variables local to the class
  # Used to ensure that only a single web page is being generated
  # These are used by the menu frame
  #############################################################################

  num_inst = 0
  f_menu = None

  #############################################################################
  # Initialise web page creation
  # Ensure only a single web page can be generated
  #############################################################################

  def __init__( self, concat_summ ) :
    if ( cl_web_page.num_inst == 0 ) :
      cl_web_page.num_inst = 1
      self.create_top_level( concat_summ )
      self.create_menu_frame( )
      self.create_results_frame( )

  #############################################################################
  # Create the top-level web page
  # Contains: all the JavaScript functions
  #           all the JavaScript data
  #           the lower frame definitions
  #############################################################################

  def create_top_level( self, concat_summ ) :
    f_top = open( 'NoPiSD_Top.html', 'wt' )
    f_top.write( '<html>\n' )
    f_top.write( '<head>\n' )

    self.include_javascript_functions( f_top )
    self.include_javascript_globals( f_top, concat_summ )

    f_top.write( '<title>Long Term Trends</title>\n' )
    f_top.write( '</head>\n' )

    self.define_frames( f_top )

    f_top.write( '<body id=top_body bgcolor="#fff5e4">\n' )
    f_top.write( '</body>\n' )
    f_top.write( '</html>\n' )
    f_top.close()

  #############################################################################
  # Read JavaScript functions from a dedicated file and include in the
  # web page
  #############################################################################

  def include_javascript_functions( self, f_top ) :
    f_js = open( 'NoPiSD_javascript.js', 'rt' )
    file_data = f_js.read()
    f_js.close()

    f_top.write( '<script language="JavaScript">\n' )
    f_top.write( file_data )
    f_top.write( '</script>\n' )


  #############################################################################
  # Generate data structures used by JavaScript
  # Comprises of an array and a structure. The array: combo_names
  # contains the list of combos read from the concatenation summary
  # file
  #############################################################################

  def include_javascript_globals( self, f_top, concat_summ ) :
    f_top.write( '<script>\n' )
    f_top.write( '  var state = {};\n' )
    f_top.write( '  state.phy_baseline = [ ];\n' )
    f_top.write( '  state.meas_type    = [ ];\n' )
    f_top.write( '  state.plot_type    = [ ];\n' )
    f_top.write( '  state.metric_idx   = [ ];\n' )
    f_top.write( '  var cright_str = \"'
                 + self.inc_copyright()
                 + '\";\n' )
    found = 0
    f_top.write( '  var combo_names = [' )
    for idx in range( concat_summ.num_combos ) :
      if ( found != 0 ) :
        f_top.write( ',' ) 
      combo_name = get_combo_short_name( concat_summ.combo[ idx ].combo_name ) 
      f_top.write( '"' + str( combo_name ) + '"' )
      found += 1
    f_top.write( '];\n' )
    f_top.write( '</script>\n' )

    
  #############################################################################
  # Generate the web page code that defines the use of frames
  #############################################################################

  def define_frames( self, f_top ) :
    f_top.write( '<frameset cols="20%,*">\n' )
    f_top.write( '<frame src="web/NoPiSD_Menu.html" name=menu_frame>\n' )
    f_top.write( '<frame src="web/NoPiSD_Results.html" name=res_frame id=res_page>\n' )
    f_top.write( '<noframes>\n' )
    f_top.write( 'Sorry, this document can be viewed only with a '
                 'frame-capable browser. Go to the '
                 '<a href="web/NoPiSD_Menu.html"> first HTML document</a> '
                 'in the set\n' )
    f_top.write( '</noframes>\n' )
    f_top.write( '</frameset>\n' )



  #############################################################################
  # Create a simple web page for the initial results frame. This is
  # more of a "welcome" page
  # This will be overwriten later using JavaScript functions
  #############################################################################

  def create_results_frame( self ) :
    f_res = open( 'web/NoPiSD_Results.html', 'wt' )
    f_res.write( '<html>\n' )
    f_res.write( '<font face=\"arial\">\n' )
    f_res.write( '<body id=res_body bgcolor="#fff5e4">\n' )
    f_res.write( '<center>\n' )
    f_res.write( '<h1>Long Term Trends Display</h1><br>\n' )
    f_res.write( '<img src="../TRMBlogoMed.png" align=middle /><br>\n' )
    f_res.write( self.inc_copyright() )
    f_res.write( '</center>\n' )
    f_res.write( '</body>\n' )
    f_res.write( '</font>\n' )
    f_res.write( '</html>\n' )
    f_res.close()


  #############################################################################
  # Complete the menu frame web page description
  #############################################################################

  def __del__( self ) :
    self.menu_text_line( self.inc_copyright() )
    self.menu_tag_line( '</font>' )
    self.menu_tag_line( '</body>' )
    self.menu_tag_line( '</html>' )
    cl_web_page.f_menu.close()


  #############################################################################
  # Begin the menu frame web page description
  #############################################################################

  def create_menu_frame( self ) :
    cl_web_page.f_menu = open( 'web/NoPiSD_Menu.html', 'wt' )
    self.menu_tag_line( '<html>' )
    self.menu_tag_line( '<title>Long Term Trends</title>' )
    self.menu_tag_line( '<body id=menu_body bgcolor="#fff5e4">' )
    self.menu_tag_line( '<font face=\"arial\">' )
    self.menu_tag_line( '<h1>Long Term Trends</h1>' )
    self.menu_tag_line( '<h2>Trends based on Physical Baseline</h2>' )

  #############################################################################
  # Describe duration for which trends were generated
  #############################################################################

  def input_data_file_section( self, concat_summ ) :
    self.menu_tag_line( '<h3>Trend Interval</h3>' )
    self.display_dates( '<b>Start Date:</b>', concat_summ.start_date )
    self.display_dates( '<b>End Date:</b>', concat_summ.end_date )
    start_date = str2obj_date( concat_summ.start_date )
    end_date = str2obj_date( concat_summ.end_date )
    duration = ( end_date - start_date ).days
    self.menu_text_line( '<b>Duration:</b>' )
    self.menu_text_line( str( duration ) + ' Days' )
    self.display_check_boxes( )

  #############################################################################
  # Include two checkboxes in the menu frame. The user
  # checkes/uncheckes these boxes to display: 
  # 1. Trends for all metrics or only mean and std trends
  # 2.Auto scaled versus fixed scale plots
  #############################################################################

  def display_check_boxes( self ) :
    cl_web_page.f_menu.write( '<br> <input type="checkbox" name="all_metrics"'
                              + ' id="all_metrics" '
                              + ' onClick="top.dynamic_plot_update()" >'
                              + ' <b>Display All Metrics </b> <br>' )
    cl_web_page.f_menu.write( '<input type="checkbox" name="auto_scale"'
                              + ' id="auto_scale"'
                              + ' onClick="top.dynamic_plot_update()" >'
                              + ' <b>Show Auto Scaled Plots </b> <br>' )

  #############################################################################
  # Utility function used to convert and display date in yyyy/mm/dd format
  #############################################################################

  def display_dates( self, label, date_in ) :
    date_obj = str2obj_date( date_in )
    label = ( label
              + '<br>'
              + str( "%04d" % date_obj.year  )
              + '-' + str( "%02d" % date_obj.month )
              + '-' + str( "%02d" % date_obj.day )
             )
    self.menu_text_line( label )

  #############################################################################
  # Include links to the plots and statistics for all satellites and all signal
  # in the menu frame
  # These links call JavaScript functions
  #############################################################################

  def create_baseline_links( self, concat_summ ) :

    # Zero Physical Baseline
    self.menu_tag_line( '<h3>Physical Baseline: Zero</h3>' )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [0], [0] )"> '
      + 'D.D. Carrier Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [0], [1] )"> '
      + 'D.D. Code Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [0], [2] )"> '
      + 'S.D. CNo Trends </a>'   
      )

    # Short Physical Baseline
    self.menu_tag_line( '<h3>Physical Baseline: Short</h3>' )

    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [1], [0] )"> '
      + 'D.D. Carrier Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [1], [1] )"> '
      + 'D.D. Code Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [1], [2] )"> '
      + 'S.D. CNo Trends </a>'   
      )

    # Antenna Switch Baseline
    self.menu_tag_line( '<h3>Physical Baseline: Antenna Switch</h3>' )

    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [2], [0] )"> '
      + 'D.D. Carrier Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [2], [1] )"> '
      + 'D.D. Code Phase Trends </a>'
      )
    self.menu_text_line(
      '<a href="javascript:top.show_trend_plots( [2], [2] )"> '
      + 'S.D. CNo Trends </a>'   
      )


  #############################################################################
  # Utility function to write a tag line to the menu frame
  # The tag line has no line break <br>
  #############################################################################

  def menu_tag_line( self, line ) :
    cl_web_page.f_menu.write( line + '\n' )


  #############################################################################
  # Utility function to write a text line to the menu frame
  # The text line has a line break <br>
  #############################################################################

  def menu_text_line( self, line ) :
    cl_web_page.f_menu.write( line + '<br>\n' )


  #############################################################################
  # Utility function to convert the signal combo name into a more readable
  # string which can be displayed
  #############################################################################

  def combo_name( self, concat_summ, combo ) :
    cname = concat_summ.combo[combo].combo_name
    [ref_sat_type, ref_sub_type, tst_sat_type, tst_sub_type] = string.split( cname )
    cname = ( convert_sat_type( ref_sat_type )
              + ' '
              + convert_sub_type( ref_sub_type )
              )

    # Only append the second signal type if it's different from the first
    if ( ( ref_sat_type != tst_sat_type )
         | ( ref_sub_type != tst_sub_type ) ) :
      cname = ( cname
                + ' / ' 
                + convert_sat_type( tst_sat_type )
                + ' '
                + convert_sub_type( tst_sub_type )
                )

    return( cname );

  #############################################################################
  # Return the copyright string
  # Included by all web pages
  #############################################################################

  def inc_copyright( self ) :
    return( '<br>&copy;Copyright Trimble Navigation 2012</br>' )

