<?xml version="1.0" encoding="utf-8"?>
<s:List xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"
        itemRenderer="de.dtele.ui.components.SourceItemRenderer"
        dropEnabled="true"
        creationComplete="onCreationComplete(event)"
        change="onChange(event)"
        dragDrop="onDrop(event)">
  
  <fx:Metadata>
    /**
     * A list of sources
     * 
     * @author Mathias Brodala
     */
    
    /**
     * Dispatched when a source was requested to be closed
     */
    [Event("sourceClose", type="de.dtele.ui.components.events.SourceListEvent")]
    /**
     * Dispatched when a source was requested to be selected
     */
    [Event("sourceSelect", type="de.dtele.ui.components.events.SourceListEvent")]
  </fx:Metadata>
  
  <fx:Declarations>
    <mx:Sort id="sourcesSort" compareFunction="compareSources"/>
  </fx:Declarations>
  
  <fx:Script>
    <![CDATA[
      import de.dtele.data.ISource;
      import de.dtele.ui.components.events.SourceListEvent;
      
      import mx.collections.ListCollectionView;
      import mx.events.DragEvent;
      import mx.events.FlexEvent;
      
      import spark.events.IndexChangeEvent;
      
      /**
       * Compares resources by the current main property
       */
      protected function compareSources(a:ISource, b:ISource, fields:Array = null):int {
        
        var aTitle:String = a.properties.title.toLowerCase();
        var bTitle:String = b.properties.title.toLowerCase();
        var result:int = aTitle.localeCompare(bTitle);
        
        // Clamp return value of String.localeCompare() to [-1, 1], to avoid an endless loop
        // @see http://tech.groups.yahoo.com/group/flexcoders/message/84186#ymg0
        return Math.max(-1, Math.min(result, 1));
      }
      
      /**
       * Prepares watching data provider changes
       */
      protected function onCreationComplete(event:FlexEvent):void {
        
        this.addEventListener("dataProviderChanged", this.onDataProviderChanged);
        // Fake event to trigger sorting
        this.dispatchEvent(new Event("dataProviderChanged"));
      }
      
      /**
       * Assigns the sorting and refreshes the data source
       */
      protected function onDataProviderChanged(e:Event):void {
        
        var listCollection:ListCollectionView = this.dataProvider as ListCollectionView;
        
        listCollection.sort = this.sourcesSort;
        listCollection.refresh();
      }

      /**
       * Notifies about the request to change the current source
       */
      protected function onChange(e:IndexChangeEvent):void {
        
        var source:ISource = this.dataProvider.getItemAt(e.newIndex) as ISource;
        
        this.dispatchEvent(new SourceListEvent(SourceListEvent.SELECT, source));
      }
      
      /**
       * Forwards the select request for a source
       */
      protected function onSourceSelect(e:SourceListEvent):void {
        
        this.dispatchEvent(e);
      }

      /**
       * Prevents the default action which removes items from their
       * data sources as this depends on whether moving or copying
       * resources actually succeeded
       *
       * @param e The DragEvent object.
       */
      protected function onSourceClose(e:SourceListEvent):void {
        
        this.dispatchEvent(e);
      }

      /**
       * 
       */
      protected function onDrop(e:DragEvent):void {
        
        this.drawFocus(false);
        
        e.preventDefault();
      }

    ]]>
  </fx:Script>
  
</s:List>