'use strict';

/**
 * @ngdoc directive
 * @name ng.directive:ngSwitch
 * @restrict EA
 *
 * @description
 * Conditionally change the DOM structure. Elements within ngSwitch but without
 * ngSwitchWhen or ngSwitchDefault directives will be preserved at the location
 * as specified in the template
 *
 * @usageContent
 * <ANY ng-switch-when="matchValue1">...</ANY>
 *   <ANY ng-switch-when="matchValue2">...</ANY>
 *   ...
 *   <ANY ng-switch-default>...</ANY>
 *   <ANY>...</ANY>
 *
 * @scope
 * @param {*} ngSwitch|on expression to match against <tt>ng-switch-when</tt>.
 * @paramDescription
 * On child elements add:
 *
 * * `ngSwitchWhen`: the case statement to match against. If match then this
 *   case will be displayed. If the same match appears multiple times, all the
 *   elements will be displayed.
 * * `ngSwitchDefault`: the default case when no other case match. If there
 *   are multiple default cases, all of them will be displayed when no other
 *   case match.
 *
 *
 * @example
    <doc:example>
      <doc:source>
        <script>
          function Ctrl($scope) {
            $scope.items = ['settings', 'home', 'other'];
            $scope.selection = $scope.items[0];
          }
        </script>
        <div ng-controller="Ctrl">
          <select ng-model="selection" ng-options="item for item in items">
          </select>
          <tt>selection={{selection}}</tt>
          <hr/>
          <div ng-switch on="selection" >
            <div ng-switch-when="settings">Settings Div</div>
            <span ng-switch-when="home">Home Span</span>
            <span ng-switch-default>default</span>
          </div>
        </div>
      </doc:source>
      <doc:scenario>
        it('should start in settings', function() {
         expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/);
        });
        it('should change to home', function() {
         select('selection').option('home');
         expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/);
        });
        it('should select default', function() {
         select('selection').option('other');
         expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/);
        });
      </doc:scenario>
    </doc:example>
 */
var NG_SWITCH = 'ng-switch';
var ngSwitchDirective = valueFn({
  restrict: 'EA',
  require: 'ngSwitch',
  // asks for $scope to fool the BC controller module
  controller: ['$scope', function ngSwitchController() {
    this.cases = {};
  }],
  link: function(scope, element, attr, ctrl) {
    var watchExpr = attr.ngSwitch || attr.on,
        selectedTranscludes,
        selectedElements,
        selectedScopes = [];

    scope.$watch(watchExpr, function ngSwitchWatchAction(value) {
      for (var i= 0, ii=selectedScopes.length; i<ii; i++) {
        selectedScopes[i].$destroy();
        selectedElements[i].remove();
      }

      selectedElements = [];
      selectedScopes = [];

      if ((selectedTranscludes = ctrl.cases['!' + value] || ctrl.cases['?'])) {
        scope.$eval(attr.change);
        forEach(selectedTranscludes, function(selectedTransclude) {
          var selectedScope = scope.$new();
          selectedScopes.push(selectedScope);
          selectedTransclude.transclude(selectedScope, function(caseElement) {
            selectedElements.push(caseElement);
            selectedTransclude.element.after(caseElement);
          });
        });
      }
    });
  }
});

var ngSwitchWhenDirective = ngDirective({
  transclude: 'element',
  priority: 500,
  require: '^ngSwitch',
  compile: function(element, attrs, transclude) {
    return function(scope, element, attr, ctrl) {
      ctrl.cases['!' + attrs.ngSwitchWhen] = (ctrl.cases['!' + attrs.ngSwitchWhen] || []);
      ctrl.cases['!' + attrs.ngSwitchWhen].push({ transclude: transclude, element: element });
    };
  }
});

var ngSwitchDefaultDirective = ngDirective({
  transclude: 'element',
  priority: 500,
  require: '^ngSwitch',
  compile: function(element, attrs, transclude) {
    return function(scope, element, attr, ctrl) {
      ctrl.cases['?'] = (ctrl.cases['?'] || []);
      ctrl.cases['?'].push({ transclude: transclude, element: element });
    };
  }
});

@@ -306,18 +306,45 @@
 sage
-Content
+%0A * %3CANY ng-switch=%22expression%22%3E
 %0A *
+  
  %3CAN
@@ -487,18 +487,8 @@
 %0A * 
-  %3CANY%3E...
 %3C/AN

improve the @usage example