/*
 * Xailer source code:
 *
 * RecentList.prg
 * Manejo de listas MRU
 *
 * Copyright 2003, 2007 Jose Lalin
 * Copyright 2003, 2007 Xailer.com
 * All rights reserved
 *
 */

#include "Xailer.ch"


//--------------------------------------------------------------------------

CLASS XRecentList FROM TComponent

PUBLISHED:
   PROPERTY aItems         INIT {}  WRITE SetItems
   PROPERTY nMaxItems      INIT 5   WRITE INLINE ::FnMaxItems := Value, ::Refresh()
   PROPERTY lAutoSave      INIT .F. WRITE INLINE ::FlAutoSave := Value, ::Refresh()
   PROPERTY lAutoRemove    INIT .F. WRITE INLINE ::FlAutoRemove := Value, ::Refresh()
   PROPERTY cIniFile       EDITOR PE_BrowseFile
   PROPERTY cIniSection

PUBLIC:
   METHOD Add( cItem )     // --> Nil
   METHOD Delete( nItem )  // --> Nil
   METHOD DeleteItems()       INLINE ::FaItems := {}, ::Refresh() // --> Nil
   METHOD Refresh()  // --> Nil
   METHOD SetItems( aItems )  INLINE ::FaItems := aItems, ::Refresh() // --> Nil

   METHOD SetIniFile( cFile, cSection ) // --> Nil
   METHOD Read( cFile, cSection ) // --> Nil
   METHOD Write( cFile, cSection ) // --> Nil

ENDCLASS

//--------------------------------------------------------------------------

METHOD Add( cItem ) CLASS XRecentList

   LOCAL nPos := AScan( ::aItems, {| x | Upper( x ) == Upper( cItem ) } )

   IF nPos > 0
      ADel( ::aItems, nPos )
      AIns( ::aItems, 1 )
      ::aItems[ 1 ] := cItem
   ELSE
      IF Len( ::aItems ) == 0
         AAdd( ::aItems, cItem )
      ELSE
         ASize( ::aItems, Len( ::aItems ) + 1 )
         AIns( ::aItems, 1 )
         ::aItems[ 1 ] := cItem
      ENDIF
   ENDIF

   ::Refresh()

RETURN Nil

//--------------------------------------------------------------------------

METHOD Delete( nItem ) CLASS XRecentList

   IF nItem > 0 .AND. nItem <= Len( ::aItems )
      ADel( ::aItems, nItem )
      ASize( ::aItems, Len( ::aItems ) - 1 )
   ENDIF

   ::Refresh()

RETURN Nil

//--------------------------------------------------------------------------

METHOD Refresh() CLASS XRecentList

   LOCAL nItems := Len( ::aItems )
   LOCAL i

   IF ::lAutoRemove

      /* Se eliminan en sentido inverso para evitar
         errores con el indice del array
      */
      FOR i := nItems TO 1 STEP -1
         IF ! File( ::aItems[ i ] )
            ADel( ::aItems, i )
            nItems--
         ENDIF
      NEXT

      ASize( ::aItems, nItems )

   ENDIF

   IF nItems > ::nMaxItems
      ASize( ::aItems, ::nMaxItems )
   ENDIF

   IF ::lAutoSave
      ::Write()
   ENDIF

RETURN Nil

//--------------------------------------------------------------------------

METHOD SetIniFile( cIniFile, cIniSection ) CLASS XRecentList

   ::cIniFile := cIniFile
   ::cIniSection := cIniSection

   IF ::cIniFile != Nil .AND. ::cIniSection != Nil
      ::Read()
   ENDIF

RETURN Nil

//--------------------------------------------------------------------------

METHOD Write( cFile, cSection ) CLASS XRecentList

   LOCAL nItems := Min( Len( ::aItems ), ::nMaxItems )
   LOCAL i

   UPDATE  ::cIniFile      TO cFile
   UPDATE  ::cIniSection   TO cSection

   DEFAULT ::cIniFile      TO FileSetExtension( Application:cFilename, ".ini" )
   DEFAULT ::cIniSection   TO "RecentList"

   WITH OBJECT TIni():New( ::cIniFile )
      :DeleteSection( ::cIniSection )
      FOR i := 1 TO nItems
         :SetEntry( ::cIniSection, LTrim( Str( i, 6 ) ), ::aItems[ i ] )
      NEXT
   END

RETURN Nil

//--------------------------------------------------------------------------

METHOD Read( cFile, cSection ) CLASS XRecentList

   LOCAL aEntries, i

   UPDATE  ::cIniFile      TO cFile
   UPDATE  ::cIniSection   TO cSection

   DEFAULT ::cIniFile      TO FileSetExtension( Application:cFilename, ".ini" )
   DEFAULT ::cIniSection   TO "RecentList"

   WITH OBJECT TIni():New( ::cIniFile )
      aEntries := :EnumSectionEntries( ::cIniSection )
      FOR i := Len( aEntries ) TO 1 Step -1
         IF ! Empty( cFile := :GetEntry( ::cIniSection, aEntries[ i ], "" ) )
            ::Add( cFile )
         ENDIF
      NEXT
   END WITH

   ::Refresh()

RETURN Nil

//--------------------------------------------------------------------------
