// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple, Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

sc_require('views/segmented');

SC.TOP_LOCATION = 'top';
SC.BOTTOM_LOCATION = 'bottom';

/** 
  @class

  Incorporates a segmented view and a container view to display the selected
  tab.  Provide an array of items, which will be passed onto the segmented
  view.
  
  @extends SC.View
  @since SproutCore 1.0
*/
SC.TabView = SC.View.extend(
/** @scope SC.TabView.prototype */ {

  classNames: ['sc-tab-view'],
  
  displayProperties: ['nowShowing'],

  // ..........................................................
  // PROPERTIES
  // 
  
  nowShowing: null,
  
  items: [],
  
  isEnabled: YES,
  
  itemTitleKey: null,
  itemValueKey: null,
  itemIsEnabledKey: null,
  itemIconKey: null,
  itemWidthKey: null,
  
  tabLocation: SC.TOP_LOCATION,
  
  /** 
    If set, then the tab location will be automatically saved in the user
    defaults.  Browsers that support localStorage will automatically store
    this information locally.
  */
  userDefaultKey: null,
  
  
  // ..........................................................
  // FORWARDING PROPERTIES
  // 
  
  // forward important changes on to child views
  _tab_nowShowingDidChange: function() {
    var v = this.get('nowShowing');
    this.get('containerView').set('nowShowing',v);
    this.get('segmentedView').set('value',v);
    return this ;
  }.observes('nowShowing'),

  _tab_saveUserDefault: function() {
    // if user default is set, save also
    var v = this.get('nowShowing');
    var defaultKey = this.get('userDefaultKey');
    if (defaultKey) {
      SC.userDefaults.set([defaultKey,'nowShowing'].join(':'), v);
    }
  }.observes('nowShowing'),
  
  _tab_itemsDidChange: function() {
    this.get('segmentedView').set('items', this.get('items'));
    return this ;    
  }.observes('items'),

  /** @private
    Restore userDefault key if set.
  */
  init: function() {
    sc_super();
    this._tab_nowShowingDidChange()._tab_itemsDidChange();
  },

  awake: function() {
    sc_super();  
    var defaultKey = this.get('userDefaultKey');
    if (defaultKey) {
      defaultKey = [defaultKey,'nowShowing'].join(':');
      var nowShowing = SC.userDefaults.get(defaultKey);
      if (!SC.none(nowShowing)) this.set('nowShowing', nowShowing);
    }

  },
  
  createChildViews: function() {
    var childViews = [], view, ContainerView ;
    
    if (this.get('tabLocation') === SC.TOP_LOCATION) {
      ContainerView = this.containerView.extend({
        layout: { top:12, left:0, right:0, bottom: 0 }
      });
    } else {
      ContainerView = this.containerView.extend({
        layout: { top:0, left:0, right:0, bottom: 12 }
      });
    }
    
    view = this.containerView = this.createChildView(ContainerView, { 
      rootElementPath: [0] 
    }) ;
    childViews.push(view);
    
    view = this.segmentedView = this.createChildView(this.segmentedView, { 
      rootElementPath: [1] 
    }) ;
    childViews.push(view);
    
    this.set('childViews', childViews);
    return this; 
  },
  
  // ..........................................................
  // COMPONENT VIEWS
  // 

  /**
    The containerView managed by this tab view.  Note that TabView uses a 
    custom container view.  You can access this view but you cannot change 
    it.
  */
  containerView: SC.ContainerView,
  
  /**
    The segmentedView managed by this tab view.  Note that this TabView uses
    a custom segmented view.  You can access this view but you cannot change
    it.
  */
  segmentedView: SC.SegmentedView.extend({
    layout: { left: 0, right: 0, height: 24 },

    /** @private
      When the value changes, update the parentView's value as well.
    */
    _sc_tab_segmented_valueDidChange: function() {
      var pv = this.get('parentView');
      if (pv) pv.set('nowShowing', this.get('value'));
      
      // FIXME: why is this necessary? 'value' is a displayProperty and should
      // automatically cause displayDidChange() to fire, which should cause 
      // the two lines below to execute in the normal course of things...
      this.set('layerNeedsUpdate', YES) ;
      this.invokeOnce(this.updateLayerIfNeeded) ;
    }.observes('value'),
    
    /** @private
      When we need to actually create a container, look for the tab loc from
      the parent view and adjust the internal frame accordingly.  Also copy
      the item key settings from the tab view.
    */
    render: function(context, firstTime) {
      sc_super();
      // copy some useful properties from the parent view first
      var pv = this.get('parentView');
      var tabLoc = (pv) ? pv.get('tabLocation') : SC.TOP_LOCATION ;
      if (tabLoc === SC.TOP_LOCATION) {
        context.addStyle('top', '0px');
      } else {
        context.addStyle('bottom', '0px');
      }
    },
    
    init: function() {
      // before we setup the rest of the view, copy key config properties 
      // from the owner view...
      var pv = this.get('parentView');
      if (pv) {
        SC._TAB_ITEM_KEYS.forEach(function(k) { this[k] = pv.get(k); }, this);
      }
      return sc_super();
    }
  })
  
}) ;

SC._TAB_ITEM_KEYS = 'itemTitleKey itemValueKey itemIsEnabledKey itemIconKey itemWidthKey'.w();