Model subclass: #Fib
    instanceVariableNames: 'nombre valeur suivant saut next '
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!


!Fib commentStamp: '<historical>' prior: 0!
une instance de FIB connait son predecceur et (s'ils
existent) ses successeurs.!


!Fib methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:19'!

next
    self changed: #displayNextOn: from: self.
    self suivant changed: #displayNextOffOn: from: self suivant.
    ^ next! !

!Fib methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:20'!
next: aValue
    next := aValue.
    self changed: #displayNextPointerOn: from: self! !

!Fib methodsFor: 'accessing'!
nombre
    ^nombre! !

!Fib methodsFor: 'accessing'!
nombre: aValue
    nombre := aValue! !

!Fib methodsFor: 'accessing'!
saut
    ^saut! !

!Fib methodsFor: 'accessing' stamp: 'hw 2/2/2001 09:23'!
saut: aValue
    saut := aValue.
    self changed: #displaySautOn: from: self! !

!Fib methodsFor: 'accessing'!
suivant
    ^suivant! !

!Fib methodsFor: 'accessing' stamp: 'hw 2/2/2001 09:22'!
suivant: aValue
    suivant := aValue.
    self changed: #displaySuivantOn: from: self.! !

!Fib methodsFor: 'accessing'!
valeur
    ^valeur! !

!Fib methodsFor: 'accessing' stamp: 'hw 2/2/2001 09:22'!
valeur: aValue
    valeur := aValue.
    self changed: #displayValueOn: from: self! !


!Fib methodsFor: 'calcul' stamp: 'hw 2/2/2001 23:51'!

find: n with: compt
    | x |
    x := self.
    (compt to: n by: -1)
        do: [:y | x := x next].
    "x next."
    ^ x valeur! !

!Fib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:21'!
findForward: n with: compt
    | x |
    x := self.
    (compt to: n - 1 by: 1)
        do: [:y | x := x suivant].
    x next.
    ^ x valeur! !

!Fib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:21'!
message: n
    self valeur: valeur + n.
    nombre := nombre + 1.
    nombre = 2
        ifTrue:
            [saut message: valeur.
            ^ suivant message: valeur]! !

!Fib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:21'!
prepare: n suivant: suiv saut: apres old: laChaine oldValue: value
    "construit la chaine des nombres de fibonnacci"
    n > value
        ifTrue:
            [self valeur: 0.
            nombre := 0.
            self saut: apres.
            self suivant: suiv.
            suiv next: self.
            ^ (self class new addDependentFrom: self;
            nbFib: n - 1)
                prepare: n - 1
                suivant: self
                saut: suiv
                old: laChaine
                oldValue: value]
        ifFalse:
            [laChaine saut: apres.
            laChaine suivant: suiv.
            suiv next: laChaine.
            laChaine next saut: suiv.
            suiv valeur: laChaine next valeur.
            suiv nombre: 1.
            laChaine nombre: 1.
            ^ laChaine message: 0]! !


!Fib methodsFor: 'initialisation' stamp: 'hw 2/3/2001 08:22'!

prepare: n suivant: suiv saut: apres
    "doit construire les premiers n nombres de fibonnacci, n'est
   
    appelee qu'une seule fois"
    n < 0 ifTrue: [^ suiv].
    self valeur: (n < 2
            ifTrue: [n]
            ifFalse: [0]).
    nombre := n < 2
                ifTrue: [1]
                ifFalse: [0].
    self saut: apres.
    self suivant: suiv.
    suiv next: self.
    ^ (self class new addDependentFrom: self;
    nbFib: n - 1)
        prepare: n - 1
        suivant: self
        saut: suiv! !


Controller subclass: #FibController
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!



!FibController methodsFor: 'menu'!

clear
    view clearInside.
    view display! !

!FibController methodsFor: 'menu'!
creation
    | val fib |
    (val := FillInTheBlank
            request: 'Valeur:') isEmpty
    ifTrue: [^self].
    val := val asNumber.
    fib := FibGraphique new.
    fib addDependent: view.
    fib nbFib: val! !

!FibController methodsFor: 'menu'!
eval
    | val x |
    (val := FillInTheBlank
            request: 'Valeur:') isEmpty
    ifTrue: [^self].
    val := val asNumber.
    x := (MemoFib newOn: view).
    MemoFib leDernierMemoFib: x.
    x fib: val! !

!FibController methodsFor: 'menu'!
max
    | x |
    x := (MemoFib leDernierMemoFib) last.
    Transcript show: x nbFib printString; cr! !

!FibController methodsFor: 'menu' stamp: 'hw 2/2/2001 22:08'!
myInspect
    MemoFib leDernierMemoFib inspect! !

!FibController methodsFor: 'menu'!
reEval
    | val x |
    (val := FillInTheBlank
            request: 'Quel nombre de Fibonacci ?') isEmpty
    ifTrue: [^self].
    val := val asNumber.
    x := MemoFib leDernierMemoFib.
    x fib: val! !

!FibController methodsFor: 'menu' stamp: 'hw 2/3/2001 08:23'!
refresh
    | x y |
    view clearInside.
    view display.
    y := MemoFib leDernierMemoFib compteur.
    x := MemoFib newOn: view.
    MemoFib leDernierMemoFib: x.
    x fib: y! !


!FibController methodsFor: 'control defaults' stamp: 'hw 2/3/2001 08:24'!

controlActivity
    | index |
    sensor yellowButtonPressed & self viewHasCursor
        ifTrue:
            [index := (PopUpMenu labels: 'creation Fib\evaluation\reEval\rafraichir\clear\max\inspect' withCRs) startUp.
            index == 0
                ifTrue: [^ self]
                ifFalse: [self perform: (#(#creation #eval #reEval #refresh #clear #max #myInspect ) at: index)]]! !

!FibController methodsFor: 'control defaults'!
isControlWanted
    ^self viewHasCursor and: [sensor blueButtonPressed not]! !


Fib subclass: #FibGraphique
    instanceVariableNames: 'fib position nbFib '
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!



!FibGraphique methodsFor: 'primitives' stamp: 'hw 2/3/2001 08:24'!

drawLine: aLine from: begp to: endp on: aView
    aLine beginPoint: begp.
    aLine endPoint: endp.
    aLine
        displayOn: Display
        transformation: aView transformation
        clippingBox: aView insetDisplayBox
        rule: Form over
        fillColor: Color black! !

!FibGraphique methodsFor: 'primitives' stamp: 'hw 2/3/2001 08:24'!
drawTerre: aLine from: begp to: endp on: aView
    | x |
    x := endp - (0 @ 2).
    self
        drawLine: aLine
        from: begp
        to: x
        on: aView.
    self
        drawLine: aLine
        from: x + (-3 @ 0)
        to: x + (3 @ 0)
        on: aView! !

!FibGraphique methodsFor: 'primitives' stamp: 'hw 2/3/2001 08:25'!
effaceTerreAt: begp with: extent on: aView
    | form aLine x |
    form := Form extent: extent.
    form fillColor: Color white.
    aLine := Line new.
    aLine form: form.
    x := begp - (0 @ 2).
    aLine beginPoint: x + (3 @ 0).
    aLine endPoint: x + (-3 @ 0).
    aLine
        displayOn: Display
        transformation: aView transformation
        clippingBox: aView insetDisplayBox
        rule: Form over
        fillColor: Color white! !

!FibGraphique methodsFor: 'primitives'!
flecheBas: aLine from: begp to: endp on: aView
    self drawLine: aLine from: begp to: endp on: aView.
    self drawLine: aLine from: endp to: endp +(-3@-2) on: aView.
    self drawLine: aLine from: endp to: endp +(2@-2) on: aView! !

!FibGraphique methodsFor: 'primitives'!
flecheGauche: aLine from: begp to: endp on: aView
    self drawLine: aLine from: begp to: endp on: aView.
    self drawLine: aLine from: endp to: endp +(3@-3) on: aView.
    self drawLine: aLine from: endp to: endp +(3@3) on: aView! !


!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:26'!

displayNextOffOn: aView
    ' ' displayOn: Display at: aView insetDisplayBox origin + position + (0 @ 30)! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:26'!
displayNextOn: aView
    '^' displayOn: Display at: aView insetDisplayBox origin + position + (0 @ 30)! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:26'!
displayNextPointerOn: aView
    | form aLine begp endp formArrivee |
    form := Form extent: 2 @ 2.
    form fillColor: Color black.
    aLine := Line new.
    aLine form: form.
    formArrivee := next nbFib printString asDisplayText form.
    begp := aView insetDisplayBox origin + position - (nbFib printString asDisplayText form width / 2 @ 0).
    endp := aView insetDisplayBox origin + next position + (formArrivee width / 2 + 1 @ 0).
    self
        flecheGauche: aLine
        from: begp
        to: endp
        on: aView! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:27'!
displayOn: aView
    | form quad |
    position := (aView insetDisplayBox extent x / 31 * (nbFib + 0.5)) asInteger @ (aView insetDisplayBox extent y / 2) asInteger.
    form := nbFib printString asDisplayText form.
    quad := Quadrangle
                region: (aView insetDisplayBox origin + position - ((form width + 4 / 2) asInteger @ (form height + 4 / 2) asInteger) extent: form width + 4 @ (form height + 4))
                borderWidth: 1
                borderColor: Color black
                insideColor: Color white.
    "self halt."
    quad
        displayOn: Display
        transformation: aView transformation
        clippingBox: aView insetDisplayBox.
    form offset: 0 @ 0 - ((form width + 2 / 2) asInteger @ (form height + 2 / 2) asInteger).
    form
        displayOn: Display
        at: aView insetDisplayBox origin + position
        clippingBox: aView insetDisplayBox
        rule: Form over
        fillColor: Color black! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:27'!
displaySautOn: aView
    | form aLine begp endp |
    form := Form extent: 2 @ 2.
    form fillColor: Color black.
    aLine := Line new.
    aLine form: form.
    begp := aView insetDisplayBox origin + position + (-2 @ -10).
    endp := begp + (0 @ -20).
    saut nbFib = 0
        ifTrue: [self
                drawTerre: aLine
                from: begp
                to: endp
                on: aView]
        ifFalse:
            [self
                drawLine: aLine
                from: begp
                to: endp
                on: aView.
            begp := endp.
            endp := begp + ((position x - saut position x) abs * 0.33 @ 0).
            self
                drawLine: aLine
                from: begp
                to: endp
                on: aView.
            "pour effacer la terre eventuelle"
            self
                effaceTerreAt: begp
                with: form extent
                on: aView.
            self
                drawLine: aLine
                from: endp
                to: aView insetDisplayBox origin + saut position - (6 @ 10)
                on: aView]! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:27'!
displaySuivantOn: aView
    | form aLine begp endp |
    form := Form extent: 1 @ 1.
    form fillColor: Color black.
    aLine := Line new.
    aLine form: form.
    begp := aView insetDisplayBox origin + position + (2 @ -10).
    endp := begp + (0 @ -15).
    suivant nbFib = 0
        ifTrue: [self
                drawTerre: aLine
                from: begp
                to: endp
                on: aView]
        ifFalse:
            [self
                drawLine: aLine
                from: begp
                to: endp
                on: aView.
            begp := endp.
            endp := begp + ((position x - suivant position x) abs * 0.55 @ 0).
            "pour effacer la terre eventuelle"
            self
                effaceTerreAt: begp
                with: form extent
                on: aView.
            self
                drawLine: aLine
                from: begp
                to: endp
                on: aView.
            self
                flecheBas: aLine
                from: endp
                to: aView insetDisplayBox origin + suivant position - (5 @ 10)
                on: aView]! !

!FibGraphique methodsFor: 'displaying' stamp: 'hw 2/3/2001 08:28'!
displayValueOn: aView
    | form quad |
    form := valeur printString asDisplayText form.
    quad := Quadrangle
                region: (aView insetDisplayBox origin + position + (0 - (form width + 4) / 2 @ (form height + 4 / 2)) extent: form width + 4 @ (form height + 4))
                borderWidth: 1
                borderColor: Color black
                insideColor: Color white.
    quad
        displayOn: Display
        transformation: aView transformation
        clippingBox: aView insetDisplayBox.
    form offset: 0 @ 0 + (0 - (form width + 2) / 2 @ (form height + 2 / 2)).
    form
        displayOn: Display
        at: aView insetDisplayBox origin + position
        clippingBox: aView insetDisplayBox
        rule: Form over
        fillColor: Color black! !


!FibGraphique methodsFor: 'accessing'!

addDependentFrom: anObject
    anObject dependents
    do: [:obj | self addDependent: obj]! !

!FibGraphique methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:28'!
fib
    ^ fib! !

!FibGraphique methodsFor: 'accessing'!
fib: aValue
    fib := aValue! !

!FibGraphique methodsFor: 'accessing' stamp: 'hw 2/1/2001 08:39'!
nbFib
    self changed: #displayOn: from: self.
    ^nbFib! !

!FibGraphique methodsFor: 'accessing' stamp: 'hw 2/1/2001 08:39'!
nbFib: aValue

    nbFib := aValue.
    self changed: #displayOn: from: self! !

!FibGraphique methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:28'!
position
    ^ position! !

!FibGraphique methodsFor: 'accessing'!
position: aValue
    position := aValue.! !


View subclass: #FibView
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!



!FibView methodsFor: 'controller access'!

defaultControllerClass
    ^FibController! !


!FibView methodsFor: 'updating' stamp: 'hw 2/1/2001 08:35'!

update: aSelector from: aSender
    aSender perform: aSelector with: self! !

!FibView methodsFor: 'updating'!
update: aSelector with: aNil from: aSender
    aSender perform: aSelector with: self! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

FibView class
    instanceVariableNames: ''!



!FibView class methodsFor: 'instanciation' stamp: 'hw 2/2/2001 22:16'!

open
    "FibView open"
    | topView |
    topView := (StandardSystemView new
                    model: nil;
                    label: 'Fibonacci';
                    minimumSize: 850 @ 100
).
    topView addSubView: (self new insideColor: Color white);
            borderWidth: 2.
    topView controller open.
! !


Model subclass: #MemoFib
    instanceVariableNames: 'first last compteur view '
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!


!MemoFib commentStamp: '<historical>' prior: 0!
Une instance de cette classe possede un souvenir de tous les nombres
de fibonacci deja calcules. A la demande on soit cherche dans l'enchainement
des nombres existants, soit on y rajoute ceux nouvellement calcules.!


!MemoFib methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:29'!

compteur
    ^compteur! !

!MemoFib methodsFor: 'accessing'!
compteur: aValue
    compteur := aValue.! !

!MemoFib methodsFor: 'accessing'!
first: aValue
    first := aValue.! !

!MemoFib methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:29'!
last
    ^last! !

!MemoFib methodsFor: 'accessing'!
last: aValue
    last := aValue.! !

!MemoFib methodsFor: 'accessing' stamp: 'hw 2/3/2001 08:29'!
view
^view! !

!MemoFib methodsFor: 'accessing'!
view: aValue
    view := aValue.! !


!MemoFib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:29'!

construct: n
    | x y |
    x := FibGraphique new.
    x addDependent: view.
    x nbFib: n.
    y := x
                prepare: n
                suivant: Resufib new
                saut: Resufib new
                old: last
                oldValue: compteur.
    last := x.
    compteur := n.
    ^ y! !

!MemoFib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:29'!
fib: n
    ^ n <= compteur
        ifTrue: [(compteur - n) abs < n abs
                ifTrue: [last find: n with: compteur]
                ifFalse: [first findForward: n with: 0]]
        ifFalse: [self construct: n]! !

!MemoFib methodsFor: 'calcul' stamp: 'hw 2/3/2001 08:30'!
show
    "pour voir les nombres de fibonacci deja construites"
    | x |
    x := last.
    (compteur to: 0 by: -1)
        do:
            [:y |
            Transcript show: 'fib(' , y printString , ') = ' , x valeur printString;
            cr.
            x := x next]! !


!MemoFib methodsFor: 'initialisation'!

initialize
    | x y |
    x := FibGraphique new.
    x nbFib: 2.
    y := x prepare: 2 suivant: (Resufib new) saut: (Resufib new).
    y message: 0.
    self last: x.
    self compteur: 2! !

!MemoFib methodsFor: 'initialisation' stamp: 'hw 1/31/2001 23:10'!
initializeOn: aView
    | x y |
    view := aView.
    x := FibGraphique new.
    x addDependent: aView.
    x nbFib: 2.
    y := x prepare: 2 suivant: (Resufib new) saut: (Resufib new).
    self first: y.
    y message: 0.
    self last: x.
    self compteur: 2.
! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

MemoFib class
    instanceVariableNames: 'leDernierMemoFib '!



!MemoFib class methodsFor: 'examples'!

test
    "FibView open"
    "MemoFib test"
    | x |
    x := MemoFib new. x fib: 20. x show! !


!MemoFib class methodsFor: 'initialisation'!

new
    ^super new initialize! !

!MemoFib class methodsFor: 'initialisation' stamp: 'hw 1/31/2001 21:28'!
newOn: aView
    ^ super new initializeOn: aView! !


!MemoFib class methodsFor: 'access'!

leDernierMemoFib
    ^leDernierMemoFib! !

!MemoFib class methodsFor: 'access'!
leDernierMemoFib: uneInstance
    leDernierMemoFib := uneInstance! !


Model subclass: #Resufib
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Fibonacci'!



!Resufib methodsFor: 'dummies'!

message: n
    ^n! !

!Resufib methodsFor: 'dummies'!
nbFib
    ^0! !

!Resufib methodsFor: 'dummies'!
next: n! !

!Resufib methodsFor: 'dummies'!
position! !