package org.pentaho.ui.xul.swt.tags;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.*;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.pentaho.ui.xul.XulComponent;
import org.pentaho.ui.xul.XulDomContainer;
import org.pentaho.ui.xul.components.XulBrowser;
import org.pentaho.ui.xul.dom.Element;
import org.pentaho.ui.xul.swt.SwtElement;

public class SwtBrowser  extends SwtElement implements XulBrowser {

  private Browser browser;
  private Composite mainPanel;
  private boolean showToolbar = true;
  private Text location;
  private ToolBar toolbar;
  private String src = "about:blank";
  private String home;
  private Composite toolbarPanel;

  public SwtBrowser(Element self, XulComponent parent, XulDomContainer container, String tagName) {
    super(tagName);
    
    Composite parentComposite = (Composite) parent.getManagedObject();
    
    mainPanel = new Composite(parentComposite, SWT.BORDER);
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    
    mainPanel.setLayout(layout);
    

    setManagedObject(mainPanel);
  }

  public void execute(String data) {
    browser.execute(data);
  }

  public String getData() {
    return ""+browser.getData();
  }

  public String getSrc() {
    return browser.getUrl();
  }

  public void setSrc(String src) {
    if(browser != null){
      browser.setUrl(src);
      location.setText(src);
    }
    this.src = src;
    if(home == null){
      home = src;
    }
  }

  public void back() {
    browser.back();
  }

  public void forward() {
    browser.forward(); 
  }

  public void home() {
    browser.setUrl(home);
  }
  
  public void reload(){
    browser.refresh();
  }
  
  public void stop(){
    browser.stop();
  }

  @Override
  public void layout() {

    toolbarPanel = new Composite(mainPanel, SWT.BORDER);
    GridData data = new GridData();
    data.horizontalAlignment = SWT.FILL;
    data.grabExcessHorizontalSpace = true;
    toolbarPanel.setLayoutData(data);

    GridLayout layout = new GridLayout(3, false);
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    toolbarPanel.setLayout(layout);
    
    toolbar = new ToolBar(toolbarPanel, SWT.FLAT | SWT.HORIZONTAL);
    ToolItem item = new ToolItem(toolbar, SWT.PUSH);
    item.setText("<");
    item.addSelectionListener(new SelectionListener(){
      public void widgetDefaultSelected(SelectionEvent se) {}
      public void widgetSelected(SelectionEvent se) {
        back();
      }
    });
    data = new GridData();
    data.horizontalSpan = 1;
    data.grabExcessHorizontalSpace = false;
    toolbar.setLayoutData(data);
    
    item = new ToolItem(toolbar, SWT.PUSH);
    item.setText(">");
    item.addSelectionListener(new SelectionListener(){
      public void widgetDefaultSelected(SelectionEvent se) {}
      public void widgetSelected(SelectionEvent se) {
        forward();
      }
    });

    item = new ToolItem(toolbar, SWT.PUSH);
    item.setText("R");
    item.addSelectionListener(new SelectionListener(){
      public void widgetDefaultSelected(SelectionEvent se) {}
      public void widgetSelected(SelectionEvent se) {
        reload();
      }
    });
    
    location = new Text(toolbarPanel, SWT.BORDER);
    location.setText(src);
    location.addKeyListener(new KeyAdapter(){
      @Override
      public void keyPressed(KeyEvent arg0) {
        if(arg0.character == SWT.CR){
          setSrc(location.getText());
        }
      }
    });
    
    data = new GridData();
    data.horizontalSpan = 2;
    data.grabExcessHorizontalSpace = true;
    data.horizontalAlignment = SWT.FILL;
    location.setLayoutData(data);
    
    
    browser = createBrowser(mainPanel);
    hookupBrowserListeners(browser, false);

    browser.addCloseWindowListener(new CloseWindowListener() {
      public void close(WindowEvent event) {
        Browser browser = (Browser)event.widget;
        Shell shell = browser.getShell();
        shell.close();
      }
    });


    browser.setUrl(src);
    
    data = new GridData();
    data.grabExcessHorizontalSpace = true;
    data.grabExcessVerticalSpace = true;
    data.verticalAlignment = SWT.FILL;
    data.horizontalAlignment = SWT.FILL;
    browser.setLayoutData(data);
    
    browser.addLocationListener(new LocationListener(){
      public void changed(LocationEvent arg0) {
        SwtBrowser.this.src = arg0.location;
        location.setText(arg0.location);
      }
      public void changing(LocationEvent arg0) {}
    });
    
    setShowtoolbar(getShowtoolbar());
    mainPanel.layout(true);
  }

  private void hookupBrowserListeners(final Browser browser, final boolean visibilityListeners) {
    browser.addOpenWindowListener(new OpenWindowListener() {
      public void open(WindowEvent event) {
        Shell shell = new Shell(browser.getShell());
        shell.setText("");
        shell.setLayout(new FillLayout());
        Browser newBrowser = new Browser(shell, SWT.NONE);
        hookupBrowserListeners(newBrowser, true);
        event.browser = newBrowser;
      }
    });
    if(!visibilityListeners){
      return;
    }
    browser.addVisibilityWindowListener(new VisibilityWindowListener() {
      public void hide(WindowEvent event) {
        Browser b = (Browser) event.widget;
        Shell shell = b.getShell();
        shell.setVisible(false);
      }

      public void show(WindowEvent event) {
        Browser b = (Browser) event.widget;
        final Shell shell = b.getShell();
        if (event.location != null) shell.setLocation(event.location);
        if (event.size != null) {
          Point size = event.size;
          shell.setSize(shell.computeSize(size.x, size.y));
        }
        if(event.addressBar){ // for some reason we're getting double-events for browser window.open clicks. The second is the one we want and it has this property
          shell.open();
        }
      }
    });
  }

  protected Browser createBrowser(Composite parent){
    return new Browser(parent, SWT.None);
  }

  public boolean getShowtoolbar() {
    return showToolbar;
  }

  public void setShowtoolbar(boolean flag) {
    this.showToolbar = flag;
    if(toolbarPanel != null){
      toolbarPanel.setVisible(flag);
      ((GridData) toolbarPanel.getLayoutData()).exclude = !showToolbar;
      mainPanel.layout(true);
    }
  }
  
  public Browser getBrowser(){
    return browser;
  }
}

@@ -6043,16 +6043,56 @@
      if(
+!%22webkit%22.equals(b.getBrowserType()) %7C%7C 
 event.ad
@@ -6153,23 +6153,22 @@
 nts for 
-browser
+safari
  window.

Fix for popup browsers not opening in Linux.