/*******************************************************************************
 * Copyright (c) 2002, 2012 Innoopract Informationssysteme GmbH.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Innoopract Informationssysteme GmbH - initial API and implementation
 *    EclipseSource - ongoing development
 ******************************************************************************/

qx.Class.define( "rwt.widgets.CTabFolder", {
  extend : rwt.widgets.base.Parent,

  construct : function() {
    this.base( arguments );
    this.setTabIndex( 1 );
    this.setHideFocus( true );
    this.setAppearance( "ctabfolder" );
    this.setOverflow( "hidden" );
    this._hasFolderListener = false;
    this._hasSelectionListener = false;
    this._hasDefaultSelectionListener = false;
    this._tabPosition = "top";
    this._tabHeight = 0;
    this._selectionForeground = null;
    this._selectionBackground = null;
    this._selectionBackgroundImage = null;
    this._selectionBackgroundGradient = null;
    this._chevron = null;
    this._chevronBounds = [ 0, 0, 0, 0 ];
    this._chevronMenu = null;
    this._unselectedCloseVisible = true;
    // Minimize/maximize buttons, initially non-existing
    this._minMaxState = "normal";  // valid states: min, max, normal
    this._maxButton = null;
    this._maxButtonBounds = [ 0, 0, 0, 0 ];
    this._minButton = null;
    this._minButtonBounds = [ 0, 0, 0, 0 ];
    this._body = new rwt.widgets.base.Parent();
    this._body.addState( "barTop" );
    this._body.setAppearance( "ctabfolder-body" );
    this.add( this._body );
    this._separator = new rwt.widgets.base.Parent();
    this._separator.setAppearance( "ctabfolder-separator" );
    this.add( this._separator );
    this._frame = new rwt.widgets.base.Parent();
    this._frame.setAppearance( "ctabfolder-frame" );
    this.add( this._frame );
    this._frameBorder = new org.eclipse.rwt.Border( 2, "solid", "black" );

    // Create horizontal line that separates the button bar from the rest of
    // the client area
    // Add resize listeners to update selection border (this._highlightXXX)
    this.addEventListener( "changeWidth", this._updateLayout, this );
    this.addEventListener( "changeHeight", this._updateLayout, this );
    // Add keypress listener to select items with left/right keys
    this.addEventListener( "keypress", this._onKeyPress, this );
    this.addEventListener( "contextmenu", this._onContextMenu, this );
  },

  destruct : function() {
    // use hideMin/MaxButton to dispose of toolTips
    this.hideMinButton();
    this.hideMaxButton();
    this.removeEventListener( "changeWidth", this._updateLayout, this );
    this.removeEventListener( "changeHeight", this._updateLayout, this );
    this.removeEventListener( "keypress", this._onKeyPress, this );
    this.removeEventListener( "contextmenu", this._onContextMenu, this );
    this._disposeObjects( "_frame", "_separator" );
    this._frameBorder.dispose();
  },

  statics : {
    BUTTON_SIZE : 18,

    MIN_TOOLTIP : "Minimize",
    MAX_TOOLTIP : "Maximize",
    RESTORE_TOOLTIP : "Restore",
    CHEVRON_TOOLTIP : "Show List",
    CLOSE_TOOLTIP : "Close",

    setToolTipTexts : function( min, max, restore, chevron, close ) {
      rwt.widgets.CTabFolder.MIN_TOOLTIP = min;
      rwt.widgets.CTabFolder.MAX_TOOLTIP = max;
      rwt.widgets.CTabFolder.RESTORE_TOOLTIP = restore;
      rwt.widgets.CTabFolder.CHEVRON_TOOLTIP = chevron;
      rwt.widgets.CTabFolder.CLOSE_TOOLTIP = close;
    }
  },

  members : {

    addState : function( state ) {
      this.base( arguments, state );
      if( state.substr( 0, 8 ) == "variant_" || state.substr( 0, 4 ) == "rwt_" ) {
        this._body.addState( state );
        this._frame.addState( state );
        this._mapItems( function( item ) {
          item.addState( state );
        } );
      }
    },

    removeState : function( state ) {
      this.base( arguments, state );
      if( state.substr( 0, 8 ) == "variant_" || state.substr( 0, 4 ) == "rwt_" ) {
        this._body.removeState( state );
        this._frame.removeState( state );
        this._mapItems( function( item ) {
          item.removeState( state );
        } );
      }
    },

    /* valid values: "top", "bottom" */
    setTabPosition : function( tabPosition ) {
      this._tabPosition = tabPosition;
      this._mapItems( function( item ) {
        item.setTabPosition( tabPosition );
      } );
      if( tabPosition == "top" ) {
        this._body.addState( "barTop" );
      } else {
        this._body.removeState( "barTop" );
      }
      this._updateLayout();
    },

    /* returns one of: "top", "bottom" */
    getTabPosition : function() {
      return this._tabPosition;
    },

    setTabHeight : function( tabHeight ) {
      this._tabHeight = tabHeight;
      var buttonTop = this._getButtonTop();
      if( this._minButton != null ) {
        this._minButton.setTop( buttonTop );
      }
      if( this._maxButton != null ) {
        this._maxButton.setTop( buttonTop );
      }
      if( this._chevron != null ) {
        this._chevron.setTop( buttonTop );
      }
      this._updateLayout();
    },

    _applyTextColor : function( value, old ) {
      this.base( arguments, value, old );
      this._mapItems( function( item ) {
        item.updateForeground();
      } );
    },

    _applyBackgroundColor : function( value, old ) {
      this._body.setBackgroundColor( value );
    },

    _applyBackgroundImage : function( value, old ) {
      this._body.setUserData( "backgroundImageSize", this.getUserData( "backgroundImageSize" ) );
      this._body.setBackgroundImage( value );
    },

    // transparent not supported, null resets color
    setSelectionForeground : function( color ) {
      this._selectionForeground = color;
      this._mapItems( function( item ) {
        item.updateForeground();
      } );
    },

    // transparent not supported, null resets color
    setSelectionBackground : function( color ) {
      this._selectionBackground = color;
      this._mapItems( function( item ) {
        item.updateBackground();
      } );
      if( color != null && !this.hasState( "rwt_FLAT" ) ) {
        this._frame.setBorder( null );
        this._frameBorder.dispose();
        this._frameBorder = new org.eclipse.rwt.Border( 2, "solid", color );
        this._frame.setBorder( this._frameBorder );
      } else {
        this._frame.resetBorder();
      }
    },

    setSelectionBackgroundImage : function( image ) {
      this._selectionBackgroundImage = image;
      this._mapItems( function( item ) {
        item.updateBackgroundImage();
      } );
    },

    setSelectionBackgroundGradient : function( gradient ) {
      this._selectionBackgroundGradient = gradient;
      this._mapItems( function( item ) {
        item.updateBackgroundGradient();
      } );
    },

    setUnselectedCloseVisible : function( value ) {
      this._unselectedCloseVisible = value;
      this._mapItems( function( item ) {
        item.updateCloseButton();
      } );
    },

    setBorderVisible : function( visible ) {
      if( visible ) {
        this.addState( "rwt_BORDER" );
      } else {
        this.removeState( "rwt_BORDER" );
      }
      this._updateLayout();
    },

    getSelectionForeground : function() {
      return this._selectionForeground;
    },

    getSelectionBackground : function() {
      return this._selectionBackground;
    },

    getSelectionBackgroundImage : function() {
      return this._selectionBackgroundImage;
    },

    getSelectionBackgroundGradient : function() {
      return this._selectionBackgroundGradient;
    },

    getUnselectedCloseVisible : function() {
      return this._unselectedCloseVisible;
    },

    _mapItems : function( func ) {
      var children = this.getChildren();
      for( var i = 0; i < children.length; i++ ) {
        if( children[ i ].classname === "rwt.widgets.CTabItem" ) {
          func( children[ i ] );
        }
      }
    },

    _getButtonTop : function() {
      return ( this._tabHeight / 2 ) - ( rwt.widgets.CTabFolder.BUTTON_SIZE / 2 );
    },

    setChevronBounds : function( left, top, width, height ) {
      this._chevronBounds = [ left, top, width, height ];
      if( this._chevron != null ) {
        this._chevron.setSpace( left, width, top, height );
      }
    },

    showChevron : function() {
      if( this._chevron == null ) {
        // Create chevron button
        this._chevron = new rwt.widgets.base.Button();
        this._chevron.setAppearance( "ctabfolder-drop-down-button" );
        this._chevron.setShow( qx.constant.Style.BUTTON_SHOW_ICON );
        this._chevron.addEventListener( "execute", this._onChevronExecute, this );
        var wm = org.eclipse.swt.WidgetManager.getInstance();
        wm.setToolTip( this._chevron, rwt.widgets.CTabFolder.CHEVRON_TOOLTIP );
        this.add( this._chevron );
      }
      this._chevron.setLeft( this._chevronBounds[ 0 ] );
      this._chevron.setTop( this._chevronBounds[ 1 ] );
      this._chevron.setWidth( this._chevronBounds[ 2 ] );
      this._chevron.setHeight( this._chevronBounds[ 3 ] );
    },

    hideChevron : function() {
      if( this._chevron != null ) {
        var wm = org.eclipse.swt.WidgetManager.getInstance();
        wm.setToolTip( this._chevron, null );
        this._chevron.removeEventListener( "execute", this._onChevronExecute, this );
        this.remove( this._chevron );
        this._chevron.dispose();
        this._chevron = null;
      }
    },

    setMinMaxState : function( state ) {
      this._minMaxState = state;
      var minIcon = "";
      var maxIcon = "";
      var minToolTip = "";
      var maxToolTip = "";
      var path = rwt.remote.Server.RESOURCE_PATH + "widget/rap/ctabfolder/";
      switch( state ) {
        case "min":
          minIcon = path + "restore.gif";
          maxIcon = path + "maximize.gif";
          minToolTip = rwt.widgets.CTabFolder.RESTORE_TOOLTIP;
          maxToolTip = rwt.widgets.CTabFolder.MAX_TOOLTIP;
          break;
        case "max":
          minIcon = path + "minimize.gif";
          maxIcon = path + "restore.gif";
          minToolTip = rwt.widgets.CTabFolder.MIN_TOOLTIP;
          maxToolTip = rwt.widgets.CTabFolder.RESTORE_TOOLTIP;
          break;
        case "normal":
          minIcon = path + "minimize.gif";
          maxIcon = path + "maximize.gif";
          minToolTip = rwt.widgets.CTabFolder.MIN_TOOLTIP;
          maxToolTip = rwt.widgets.CTabFolder.MAX_TOOLTIP;
          break;
      }
      var wm = org.eclipse.swt.WidgetManager.getInstance();
      if( this._minButton != null ) {
        this._minButton.setIcon( minIcon );
        wm.setToolTip( this._minButton, minToolTip );
      }
      if( this._maxButton != null ) {
        this._maxButton.setIcon( maxIcon );
        wm.setToolTip( this._maxButton, maxToolTip );
      }
    },

    setMaxButtonBounds : function( left, top, width, height ) {
      this._maxButtonBounds = [ left, top, width, height ];
      if( this._maxButton != null ) {
        this._maxButton.setSpace( left, width, top, height );
      }
    },

    showMaxButton : function() {
      if( this._maxButton == null ) {
        this._maxButton = new rwt.widgets.base.Button();
        this._maxButton.setAppearance( "ctabfolder-button" );
        this._maxButton.setShow( qx.constant.Style.BUTTON_SHOW_ICON );
        this.setMinMaxState( this._minMaxState );  // initializes the icon according to current state
        // [if] "mousedown" is used instead of "execute" because of the bug 247672
        this._maxButton.addEventListener( "mousedown", this._onMinMaxExecute, this );
        this.add( this._maxButton );
      }
      this._maxButton.setLeft( this._maxButtonBounds[ 0 ] );
      this._maxButton.setTop( this._maxButtonBounds[ 1 ] );
      this._maxButton.setWidth( this._maxButtonBounds[ 2 ] );
      this._maxButton.setHeight( this._maxButtonBounds[ 3 ] );
    },

    hideMaxButton : function() {
      if( this._maxButton != null ) {
        this._maxButton.removeEventListener( "mousedown",
                                             this._onMinMaxExecute,
                                             this );
        var wm = org.eclipse.swt.WidgetManager.getInstance();
        wm.setToolTip( this._maxButton, null );
        this.remove( this._maxButton );
        this._maxButton.dispose();
        this._maxButton = null;
      }
    },

    setMinButtonBounds : function( left, top, width, height ) {
      this._minButtonBounds = [ left, top, width, height ];
      if( this._minButton != null ) {
        this._minButton.setSpace( left, width, top, height );
      }
    },

    showMinButton : function() {
      if( this._minButton == null ) {
        this._minButton = new rwt.widgets.base.Button();
        this._minButton.setAppearance( "ctabfolder-button" );
        this._minButton.setShow( qx.constant.Style.BUTTON_SHOW_ICON );
        this.setMinMaxState( this._minMaxState );  // initializes the icon according to current state
        // [if] "mousedown" is used instead of "execute" because of the bug 247672
        this._minButton.addEventListener( "mousedown", this._onMinMaxExecute, this );
        this.add( this._minButton );
      }
      this._minButton.setLeft( this._minButtonBounds[ 0 ] );
      this._minButton.setTop( this._minButtonBounds[ 1 ] );
      this._minButton.setWidth( this._minButtonBounds[ 2 ] );
      this._minButton.setHeight( this._minButtonBounds[ 3 ] );
    },

    hideMinButton : function( left ) {
      if( this._minButton != null ) {
        this._minButton.removeEventListener( "mousedown",
                                             this._onMinMaxExecute,
                                             this );
        var wm = org.eclipse.swt.WidgetManager.getInstance();
        wm.setToolTip( this._minButton, null );
        this.remove( this._minButton );
        this._minButton.dispose();
        this._minButton = null;
      }
    },

    setHasFolderListener : function( hasFolderListener ) {
      this._hasFolderListener = hasFolderListener;
    },

    setHasSelectionListener : function( value ) {
      this._hasSelectionListener = value;
    },

    setHasDefaultSelectionListener : function( value ) {
      this._hasDefaultSelectionListener = value;
    },

    deselectAll : function() {
      this._mapItems( function( item ) {
        item.setSelected( false );
      } );
    },

    _updateLayout : function() {
      // TODO [rst] take actual border width into account
      var borderWidth = this.hasState( "rwt_BORDER" ) ? 1 : 0;
      var frameWidth = this.hasState( "rwt_FLAT" ) ? 0 : 2;
      var sepBorderWidth = 1;
      var width = this.getWidth() - borderWidth * 2;
      var tabHeight = this._tabHeight + 1;

      this._body.setLeft( 0 );
      this._body.setTop( 0 );
      this._body.setWidth( this.getWidth() );
      this._body.setHeight( this.getHeight() );

      this._separator.setLeft( borderWidth );
      this._separator.setWidth( width );
      this._separator.setHeight( 10 );

      this._frame.setLeft( borderWidth );
      this._frame.setWidth( width );
      this._frame.setHeight( this.getHeight() - borderWidth - sepBorderWidth - tabHeight );

      if( this._tabPosition == "top" ) {
        this._separator.setTop( tabHeight );
        this._frame.setTop( tabHeight + 1 );
      } else { // tabPosition == "bottom"
        this._separator.setTop( this.getHeight() - tabHeight - 1 );
        this._frame.setTop( borderWidth );
      }
    },

    _onChevronExecute : function( evt ) {
      if( this._chevronMenu == null || !this._chevronMenu.isSeeable() ) {
        if( !org.eclipse.swt.EventUtil.getSuspended() ) {
          var wm = org.eclipse.swt.WidgetManager.getInstance();
          var id = wm.findIdByWidget( this );
          var req = rwt.remote.Server.getInstance();
          req.addEvent( "org.eclipse.swt.events.ctabFolderShowList", id );
          req.send();
        }
      }
    },

    _onMinMaxExecute : function( evt ) {
      if( !org.eclipse.swt.EventUtil.getSuspended() ) {
        var event;
        if ( evt.getTarget() == this._minButton ) {
          // Minimize button was pressed
          if( this._minMaxState == "min" ) {
            this.setMinMaxState( "normal" );
            event = "org.eclipse.swt.events.ctabFolderRestored";
          } else {
            this.setMinMaxState( "min" );
            event = "org.eclipse.swt.events.ctabFolderMinimized";
          }
        } else {
          // Maximize button was pressed
          if( this._minMaxState == "normal" || this._minMaxState == "min" ) {
            this.setMinMaxState( "max" );
            event = "org.eclipse.swt.events.ctabFolderMaximized";
          } else {
            this.setMinMaxState( "normal" );
            event = "org.eclipse.swt.events.ctabFolderRestored";
          }
        }
        var id = org.eclipse.swt.WidgetManager.getInstance().findIdByWidget( this );
        var req = rwt.remote.Server.getInstance();
        req.addParameter( id + ".minimized", this._minMaxState == "min" );
        req.addParameter( id + ".maximized", this._minMaxState == "max" );
        if( this._hasFolderListener ) {
          req.addEvent( event, id );
          req.send();
        }
      }
    },

    _onKeyPress : function( evt ) {
      switch( evt.getKeyIdentifier() ) {
        case "Left":
          // TODO [rh] implementatin missing: select tab item to the left
          evt.stopPropagation();
          break;
        case "Right":
          // TODO [rh] implementatin missing: select tab item to the right
          evt.stopPropagation();
          break;
      }
    },

    _onContextMenu : function( evt ) {
      var menu = this.getContextMenu();
      if( menu != null ) {
        menu.setLocation( evt.getPageX(), evt.getPageY() );
        menu.setOpener( this );
        menu.show();
        evt.stopPropagation();
      }
    },

    // TODO [rst] Change to respect _hasSelectionListener as soon as server-side
    // code is revised accordingly -> CTabFolderLCA.readData().
    _notifyItemClick : function( item ) {
      if( !org.eclipse.swt.EventUtil.getSuspended() ) {
        if( !item.isSelected() ) {
          this.deselectAll();
          item.setSelected( true );
          var widgetManager = org.eclipse.swt.WidgetManager.getInstance();
          var req = rwt.remote.Server.getInstance();
          var id = widgetManager.findIdByWidget( this );
          var itemId = widgetManager.findIdByWidget( item );
          req.addParameter( id + ".selection", itemId );
          req.addEvent( "org.eclipse.swt.events.Selection", id );
          org.eclipse.swt.EventUtil.addWidgetSelectedModifier();
          req.send();
        }
      }
    },

    _notifyItemDblClick : function( evt ) {
      if( !org.eclipse.swt.EventUtil.getSuspended() ) {
        if( this._hasDefaultSelectionListener ) {
          var item = evt.getTarget();
          var widgetManager = org.eclipse.swt.WidgetManager.getInstance();
          var req = rwt.remote.Server.getInstance();
          var id = widgetManager.findIdByWidget( this );
          var itemId = widgetManager.findIdByWidget( item );
          // TODO [rst] remove this parameter as soon as server-side code is revised
          //      -> CTabFolderLCA.readData()
          req.addParameter( id + ".selection", itemId );
          org.eclipse.swt.EventUtil.widgetDefaultSelected( evt, this );
        }
      }
    }
  }
} );
