export default ( React : Object ) => rs( React ).compose({
  init () {
    UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);

    this.state = {
      big: false,
    };
  },

  _onPress () {
    LayoutAnimation.spring();
    this.setState({ big: ! this.state.big });
  },

  render () {
    const { big } = this.state;

    return (
      <View style={styles.container}>
        <View style={styles.filler} />

        <TouchableWithoutFeedback onPress={e => this._onPress()}>
          <View style={[ big && styles.flex ]}>
            <Text style={styles.text}>Click Me</Text>
          </View>
        </TouchableWithoutFeedback>

        <View style={styles.filler} />
      </View>
    );
  },
});
export default ( React : Object ) => {
  const Todo = TodoFactory( React );

  return rs( React ).compose({
    init () {
      const { todos } = this.props;
      const dataSource = new ListView.DataSource({
        rowHasChanged: ( r1: Object, r2: Object ) => r1 !== r2,
      });

      this.state = {
        dataSource,
        newTodo: '',
      };
      this._setTodos( todos );
    },

    _setTodos ( todos ) {
      this.state = {
        dataSource: this.state.dataSource.cloneWithRows( todos ),
      };
    },

    _addTodo () {
      this.props.addTodo( this.state.newTodo );
      this.setState({ newTodo: '' });
    },

    componentWillReceiveProps ( nextProps ) {
      this._setTodos( nextProps.todos );
    },

    render () {
      const { dataSource } = this.state;
      const { rmTodo } = this.props;

      return (
        <View style={styles.container}>
          <TextInput
            style={styles.input}
            placeholder='Add a new todo'
            onChangeText={newTodo => this.setState({ newTodo })}
            value={this.state.newTodo}
            onSubmitEditing={() => this._addTodo()}
          />

          <ListView
            style={{ flex: 1 }}
            dataSource={dataSource}
            renderRow={d => <Todo {...d} onDelete={ rmTodo } />}
            enableEmptySections={true}
          />
        </View>
      );
    },
  });
};
export default ( React : Object, ...behaviours : Array<Object> )  => rs( React ).compose({
  render () {
    return (
      <View style={styles.container}>
        <StatusBar
          translucent={false}
          backgroundColor="rgba(0,0,0,0.3)"
          barStyle="default"
        />
        <RN2Navigator />
      </View>
    );
  },
}, ...behaviours );
export default ( React : Object ) => rs( React ).compose({
  init () {
    this.state = {
      position: { coords: {} },
    };
  },

  componentDidMount () {
    navigator.geolocation.getCurrentPosition(
      position => this.setState({ position }),
      err => console.warn( err.message ),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
    );

    this.geoWatchId = navigator.geolocation.watchPosition(
      position => this.setState({ position })
    );
  },

  componentWillUnmount () {
    navigator.geolocation.clearWatch( this.geoWatchId );
  },

  render () {
    const { position: { coords } } = this.state;

    return (
      <View style={styles.container}>
        <MapView
          style={styles.map}
          showsUserLocation={true}
          followUserLocation={true}
        />

        <View style={styles.coords}>
          <Text style={styles.label}>
            Lat, Long:
          </Text>
          <Text style={styles.value}>
            {`( ${coords.latitude}, ${coords.longitude} )`}
          </Text>
        </View>
      </View>
    );
  },
});
export default ( React : Object ) => rs( React ).compose({
  init () {
    this.state = {
      bounceValue: new Animated.Value( 0 ),
    };
  },

  componentDidMount () {
    const { bounceValue } = this.state;

    bounceValue.setValue( 1.5 );

    Animated.spring(
      bounceValue,
      {
        toValue: 1,
        friction: 1,
      }
    ).start();
  },

  render () {
    const { bounceValue } = this.state;

    return (
      <View style={styles.container}>
        <Animated.Image
          source={{ uri: imageUrl }}
          style={[ styles.image, {
            transform: [
              { scale: bounceValue },
            ],
          }]}
        />
      </View>
    );
  },
});
export default ( React : Object, ...behaviours : Array<Object> ) => rs( React ).compose({
  init () {
    const content = [];
    const Test = TestFactory( React );
    const addTest = ( name: String, render: Function ) => content.push(
      <Test key={name} render={render} />
    );

    Component.__tests__( addTest, React );

    this.state = { content };
  },

  render () {
    const { content } = this.state;

    return (
      <View style={styles.playground}>
        { content }
      </View>
    );
  },
}, ...behaviours );