package brn.gui.reports;

import java.awt.Toolkit;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.birt.report.designer.core.model.SessionHandleAdapter;
import org.eclipse.birt.report.designer.ui.ReportPlugin;
import org.eclipse.birt.report.designer.ui.preview.editors.ReportPreviewFormPage;
import org.eclipse.birt.report.model.api.ModuleHandle;
import org.eclipse.birt.report.viewer.ViewerPlugin;
import org.eclipse.birt.report.viewer.utilities.LogUtil;
import org.eclipse.birt.report.viewer.utilities.WebViewer;
import org.eclipse.birt.report.viewer.utilities.WebappAccessor;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.widgets.Composite;

public class ReportPreviewFormPage2 extends ReportPreviewFormPage {

  private static final String UTF_8 = "utf-8"; //$NON-NLS-1$
  /**
   * HTML format name
   */
  public final static String HTML = "html"; //$NON-NLS-1$
  public final static String HTM = "htm"; //$NON-NLS-1$

  /**
   * PDF format name
   */
  public final static String PDF = "pdf"; //$NON-NLS-1$

  /**
   * DOC format name
   */
  public final static String DOC = "doc"; //$NON-NLS-1$

  /**
   * POSTSCRIPT format name
   */
  public final static String POSTSCRIPT = "postscript"; //$NON-NLS-1$

  /**
   * Report extension
   */
  public static final String REPORT_DOCUMENT_FILE = ".rptdocument"; //$NON-NLS-1$

  /**
   * Birt web viewer plugin id
   */
  public final static String WebAppPlugin = ViewerPlugin.PLUGIN_ID;

  /**
   * locale preference name
   */
  public final static String USER_LOCALE = "user_locale"; //$NON-NLS-1$

  /**
   * Preference key for SVG chart flag.
   */
  public final static String SVG_FLAG = "svg_flag"; //$NON-NLS-1$

  /**
   * Preference key for master page content flag.
   */
  public final static String MASTER_PAGE_CONTENT = "master_page_content"; //$NON-NLS-1$

  /** Preference key for max rows. */
  public final static String PREVIEW_MAXROW = "preview_maxrow"; //$NON-NLS-1$

  /** Preference key for max cube fetch levels. */
  public final static String PREVIEW_MAXCUBEROWLEVEL = "preview_maxrowlevelmember"; //$NON-NLS-1$

  public final static String PREVIEW_MAXCUBECOLUMNLEVEL = "preview_maxcolumnlevelmember"; //$NON-NLS-1$

  /** Preference key for max in-memory cube size. */
  public final static String PREVIEW_MAXINMEMORYCUBESIZE = "preview_maxinmemorycubesize"; //$NON-NLS-1$

  // preview model.
  public static final String VIEWER_PREVIEW = "preview"; //$NON-NLS-1$

  // frameset model.
  public static final String VIEWER_FRAMESET = "frameset"; //$NON-NLS-1$

  // running model.
  public static final String VIEWER_RUN = "run"; //$NON-NLS-1$

  // document model
  public static final String VIEWER_DOCUMENT = "document"; //$NON-NLS-1$

  // parameter name constants for the URL

  /**
   * Key to indicate the format of the preview.
   */
  public final static String FORMAT_KEY = "FORMAT_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'allowPage' control of the preview.
   */
  public final static String ALLOW_PAGE_KEY = "ALLOW_PAGE_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'servletName' of the preview.
   */
  public final static String SERVLET_NAME_KEY = "SERVLET_NAME_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'documentName' of the preview.
   */
  public final static String DOCUMENT_NAME_KEY = "DOCUMENT_NAME_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'resourceFolder'.
   */
  public final static String RESOURCE_FOLDER_KEY = "RESOURCE_FOLDER_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate whether close window after complete
   */
  public final static String CLOSE_WINDOW_KEY = "CLOSE_WINDOW_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate which appcontext extension is loaded
   */
  public final static String APPCONTEXT_EXTENSION_KEY = "APPCONTEXT_EXTENSION_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'maxRows'
   */
  public final static String MAX_ROWS_KEY = "MAX_ROWS_KEY"; //$NON-NLS-1$

  /**
   * Key to indicate the 'maxLevelMember'
   */
  public final static String MAX_CUBE_ROW_LEVELS_KEY = "MAX_CUBE_ROW_LEVELS_KEY"; //$NON-NLS-1$

  public final static String MAX_CUBE_COLUMN_LEVELS_KEY = "MAX_CUBE_COLUMN_LEVELS_KEY"; //$NON-NLS-1$

  /**
   * Property to indicate whether it is a report debug mode
   */
  public final static String REPORT_DEBUT_MODE = "report_debug_mode"; //$NON-NLS-1$

  public void createPartControl( Composite parent ) {
    super.createPartControl(parent);
    
//    try {
//      SessionHandleAdapter.getInstance().getSessionHandle().closeAll(false);
//    } catch (IOException e1) {
//      // TODO Auto-generated catch block
//      e1.printStackTrace();
//    }
//
//    PreviewEditorInput input = (PreviewEditorInput) getEditorInput();
    ModuleHandle model = getProvider( ).getReportModuleHandle( getEditorInput() );
////    model = (ModuleHandle) getModel();
//    List parameters = model.getFlattenParameters( );
//    for ( int i = 0; i < parameters.size( ); i++ )
//    {
//      if ( parameters.get( i ) instanceof ScalarParameterHandle ) {
//        ScalarParameterHandle parameter = (ScalarParameterHandle) parameters.get( i );
//    
//        try {
//          if (parameter.getName().equals("dbDriver"))
//              parameter.setValueExpr(input.getDriver());
//          if (parameter.getName().equals("dbUrl"))
//            parameter.setValueExpr(input.getUrl());
//          if (parameter.getName().equals("dbUser"))
//            parameter.setValueExpr(input.getUser());
//          if (parameter.getName().equals("dbPassword"))
//            parameter.setValueExpr(input.getPassword());
//        } catch (SemanticException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//        }
//      }
//    }
//    
//
//    ModuleHandle model = SessionHandleAdapter.getInstance().getReportDesignHandle();
//    parameters = model.getFlattenParameters( );
//    ParameterHandle h = model.findParameter("dbUrl");
//    OdaDataSourceHandle dataSourceHandle = (OdaDataSourceHandle) model.findDataSource( "localhost" );
//    try {
//      dataSourceHandle.setStringProperty("odaDriverClass", input.getDriver());
//      dataSourceHandle.setStringProperty("odaURL", input.getUrl());
//      dataSourceHandle.setStringProperty("odaUser", input.getUser());
//      dataSourceHandle.setStringProperty("odaPassword", input.getPassword());
//    } catch (SemanticException e) {
//      // TODO Auto-generated catch block
//      e.printStackTrace();
//    }

    // Resets the mediator
    SessionHandleAdapter.getInstance().resetReportDesign(null, model);

    SessionHandleAdapter.getInstance().setReportDesignHandle(model);
    
    
    this.refresh();
  }

  /**
   * Refresh swt browser
   */
  public void display( )
  {
    Browser browser = this.getBrowser();
    
    if ( browser != null )
    {
      String uri = getFileUri( );

      if ( uri != null && uri.length( ) > 0 )
      {
        Map options = new HashMap( );
        options.put( WebViewer.SERVLET_NAME_KEY,
            "run");
        options.put( WebViewer.FORMAT_KEY, WebViewer.HTML );
        options.put( WebViewer.RESOURCE_FOLDER_KEY,
            ReportPlugin.getDefault( ).getResourceFolder( ) );
        options.put( WebViewer.MAX_ROWS_KEY,
            ViewerPlugin.getDefault( )
                .getPluginPreferences( )
                .getString( WebViewer.PREVIEW_MAXROW ) );
        options.put( WebViewer.MAX_CUBE_ROW_LEVELS_KEY,
            ViewerPlugin.getDefault( )
                .getPluginPreferences( )
                .getString( WebViewer.PREVIEW_MAXCUBEROWLEVEL ) );
        options.put( WebViewer.MAX_CUBE_COLUMN_LEVELS_KEY,
            ViewerPlugin.getDefault( )
                .getPluginPreferences( )
                .getString( WebViewer.PREVIEW_MAXCUBECOLUMNLEVEL ) );
        String extKey = ViewerPlugin.getDefault( )
            .getPluginPreferences( )
            .getString( WebViewer.APPCONTEXT_EXTENSION_KEY );
        if ( extKey != null && extKey.length( ) > 0 )
          options.put( WebViewer.APPCONTEXT_EXTENSION_KEY,
              extKey );
        
        display( uri, browser, options );
      }
    }
  }

  public void display( String report, Browser browser, Map params )
  {
    PreviewEditorInput input = (PreviewEditorInput) getEditorInput();
    WebViewer.startup();
    browser.setUrl(createURL( report, params )
        + "&dbDriver=" + input.getDriver()
        + "&dbUrl=" + input.getUrl()
        + "&dbUser=" + input.getUser()
        + "&dbPassword=" + input.getPassword()
        + "&" + new Random( ).nextInt( ));
  }

  private static String createURL( String report, Map params )
  {
    if ( params == null || params.isEmpty( ) )
      return createURL( null, report, null, null, null, null, null );
    String servletName = (String) params.get( SERVLET_NAME_KEY );
    String format = (String) params.get( FORMAT_KEY );
    String resourceFolder = (String) params.get( RESOURCE_FOLDER_KEY );
    Boolean allowPage = (Boolean) params.get( ALLOW_PAGE_KEY );

    if ( format == null || format.trim( ).length( ) <= 0
        || HTM.equalsIgnoreCase( format ) )
      format = HTML;

    if ( !HTML.equalsIgnoreCase( format ) )
    {
      servletName = VIEWER_PREVIEW;
    }
    else
    {
      if ( servletName == null || servletName.trim( ).length( ) <= 0 )
      {
        if ( allowPage == null )
          servletName = VIEWER_FRAMESET;
        else
        {
          servletName = allowPage.booleanValue( )
              ? VIEWER_FRAMESET
              : VIEWER_PREVIEW;
        }
      }
    }

    // max rows setting
    String maxrows = (String) params.get( MAX_ROWS_KEY );

    // max level member setting
    String maxrowlevels = (String) params.get( MAX_CUBE_ROW_LEVELS_KEY );
    String maxcolumnlevels = (String) params
        .get( MAX_CUBE_COLUMN_LEVELS_KEY );

    String url = createURL( servletName, report, format, resourceFolder,
        maxrows, maxrowlevels, maxcolumnlevels );

    // if document mode, append document parameter in URL
    String documentName = (String) params.get( DOCUMENT_NAME_KEY );
    if ( documentName != null && VIEWER_DOCUMENT.equals( servletName ) )
    {
      // current opened report isn't document
      if ( !isReportDocument( report ) )
      {
        try
        {
          String encodedDocumentName = URLEncoder.encode(
              documentName, UTF_8 );
          url += "&__document=" + encodedDocumentName; //$NON-NLS-1$

          String isCloseWin = (String) params.get( CLOSE_WINDOW_KEY );
          if ( isCloseWin != null )
            url += "&__closewin=" + isCloseWin; //$NON-NLS-1$
        }
        catch ( UnsupportedEncodingException e )
        {
          LogUtil.logWarning( e.getLocalizedMessage( ), e );
        }
      }
    }

    // append appcontext extension name
    String appContextName = ViewerPlugin.getDefault( )
        .getPluginPreferences( ).getString( APPCONTEXT_EXTENSION_KEY );
    if ( appContextName != null && appContextName.trim( ).length( ) > 0 )
    {
      try
      {
        String encodedAppContextName = URLEncoder.encode(
            appContextName.trim( ), UTF_8 );
        url += "&__appcontextname=" + encodedAppContextName; //$NON-NLS-1$
      }
      catch ( UnsupportedEncodingException e )
      {
        LogUtil.logWarning( e.getLocalizedMessage( ), e );
      }
    }

    return url;
  }

  private static String createURL( String servletName, String report,
      String format, String resourceFolder, String maxrows,
      String maxrowlevels, String maxcolumnlevels )
  {
    String encodedReportName = null;

    try
    {
      encodedReportName = URLEncoder.encode( report, UTF_8 );
    }
    catch ( UnsupportedEncodingException e )
    {
      LogUtil.logWarning( e.getLocalizedMessage( ), e );
    }

    String locale = ViewerPlugin.getDefault( ).getPluginPreferences( )
        .getString( USER_LOCALE );

//    if ( LocaleTable.containsKey( locale ) )
//    {
//      locale = (String) LocaleTable.get( locale );
//    }
//    else
//    {
//      if ( "".equals( locale ) ) //$NON-NLS-1$
//      {
//        locale = null;
//      }
//      else
//      {
        try
        {
          locale = URLEncoder.encode( locale, UTF_8 );
        }
        catch ( UnsupportedEncodingException e )
        {
          locale = null;
          LogUtil.logWarning( e.getLocalizedMessage( ), e );
        }
//      }
//    }
    
    String svgFlag = ViewerPlugin.getDefault( ).getPluginPreferences( )
        .getString( SVG_FLAG );
    boolean bSVGFlag = false;

    // cube memory size
    String cubeMemorySize = ViewerPlugin.getDefault( )
        .getPluginPreferences( )
        .getString( PREVIEW_MAXINMEMORYCUBESIZE );

    // get -dir rtl option
    boolean rtl = false;
    String eclipseCommands = System.getProperty( "eclipse.commands" ); //$NON-NLS-1$
    if ( eclipseCommands != null )
    {
      String[] options = eclipseCommands.split( "-" ); //$NON-NLS-1$
      String regex = "[\\s]*[dD][iI][rR][\\s]*[rR][tT][lL][\\s]*"; //$NON-NLS-1$
      Pattern pattern = Pattern.compile( regex );
      for ( int i = 0; i < options.length; i++ )
      {
        String option = options[i];
        if ( pattern.matcher( option ).matches( ) )
        {
          rtl = true;
          break;
        }
      }
    }

    if ( "true".equalsIgnoreCase( svgFlag ) ) //$NON-NLS-1$
    {
      bSVGFlag = true;
    }

    String masterPageContent = ViewerPlugin.getDefault( )
        .getPluginPreferences( ).getString( MASTER_PAGE_CONTENT );
    boolean bMasterPageContent = true;
    if ( "false".equalsIgnoreCase( masterPageContent ) ) //$NON-NLS-1$
    {
      bMasterPageContent = false;
    }

    // handle resource folder encoding
    String encodedResourceFolder = null;

    try
    {
      if ( resourceFolder != null )
        encodedResourceFolder = URLEncoder.encode( resourceFolder,
            UTF_8 );
    }
    catch ( UnsupportedEncodingException e )
    {
      LogUtil.logWarning( e.getLocalizedMessage( ), e );
    }
    if ( encodedResourceFolder == null )
      encodedResourceFolder = ""; //$NON-NLS-1$

    String reportParam = "__report"; //$NON-NLS-1$
    if ( isReportDocument( encodedReportName ) )
      reportParam = "__document"; //$NON-NLS-1$
    reportParam += "=" + encodedReportName; //$NON-NLS-1$

    // workaround for postscript format, force "Content-Disposition" as
    // "attachment"
    String asattachment = null;
    if ( POSTSCRIPT.equalsIgnoreCase( format ) )
      asattachment = "&__asattachment=true"; //$NON-NLS-1$  

    // get the local DPI setting
    int dpi = Toolkit.getDefaultToolkit( ).getScreenResolution( );

    // So far, only report name is encoded as utf-8 format
    return getBaseURL( )
        + servletName
        + "?" //$NON-NLS-1$
        + reportParam
        + "&__format=" + format //$NON-NLS-1$
        + "&__svg=" + String.valueOf( bSVGFlag ) //$NON-NLS-1$
        + ( locale != null ? "&__locale=" + locale : "" ) //$NON-NLS-1$ //$NON-NLS-2$
        + "&__masterpage=" + String.valueOf( bMasterPageContent ) //$NON-NLS-1$
        + "&__rtl=" + String.valueOf( rtl ) //$NON-NLS-1$
        + ( maxrows != null && maxrows.trim( ).length( ) > 0
            ? "&__maxrows=" + maxrows : "" ) //$NON-NLS-1$ //$NON-NLS-2$
        + ( maxrowlevels != null && maxrowlevels.trim( ).length( ) > 0
            ? "&__maxrowlevels=" + maxrowlevels : "" ) //$NON-NLS-1$ //$NON-NLS-2$
        + ( maxcolumnlevels != null
            && maxcolumnlevels.trim( ).length( ) > 0
            ? "&__maxcolumnlevels=" + maxcolumnlevels : "" ) //$NON-NLS-1$ //$NON-NLS-2$
        + ( cubeMemorySize != null
            && cubeMemorySize.trim( ).length( ) > 0
            ? "&__cubememsize=" + cubeMemorySize : "" ) //$NON-NLS-1$ //$NON-NLS-2$
        + "&__resourceFolder=" + encodedResourceFolder //$NON-NLS-1$
        + ( asattachment != null ? asattachment : "" ) //$NON-NLS-1$
        + "&__dpi=" + dpi; //$NON-NLS-1$
  }

  private static String getBaseURL( )
  {
    return "http://" + WebappAccessor.getHost( ) + ":" //$NON-NLS-1$ //$NON-NLS-2$
        + WebappAccessor.getPort("viewer") + "/viewer/"; //$NON-NLS-1$
  }

  private static boolean isReportDocument( String reportName )
  {
    if ( reportName == null )
      return false;

    Pattern p = Pattern.compile( ".[a-z]{3}document$" ); //$NON-NLS-1$
    Matcher m = p.matcher( reportName );
    if ( m.find( ) )
      return true;

    return false;
  }

}
