package main import ( "fmt" ) //------------------------------------------------\\ // + + + T Y P E S + + + \\ //--------------------------------------------------\\ // Pages is a struct that represents the history of the client. // It functions as a container for the pages (history array) and // tracks the current history length and location. type Pages struct { Position int Length int History [20]Page } //------------------------------------------------\\ // + + + R E C E I V E R S + + + \\ //--------------------------------------------------\\ // NavigateHistory takes a positive or negative integer // and updates the current history position. Checks are done // to make sure that the position moved to is a valid history // location. Returns an error or nil. func (p *Pages) NavigateHistory(qty int) error { newPosition := p.Position + qty if newPosition < 0 { return fmt.Errorf("You are already at the beginning of history") } else if newPosition > p.Length-1 { return fmt.Errorf("Your way is blocked by void, there is nothing forward") } p.Position = newPosition return nil } // Add gets passed a Page, which gets added to the history // array. Add also updates the current length and position // of the Pages struct to which it belongs. Add also shifts // off array items if necessary. func (p *Pages) Add(pg Page) { if p.Position == p.Length-1 && p.Length < len(p.History) { p.History[p.Length] = pg p.Length++ p.Position++ } else if p.Position == p.Length-1 && p.Length == 20 { for x := 1; x < len(p.History); x++ { p.History[x-1] = p.History[x] } p.History[len(p.History)-1] = pg } else { p.Position++ p.Length = p.Position + 1 p.History[p.Position] = pg } } // Render wraps the content for the current page and returns // the page content as a string slice func (p *Pages) Render(termHeight, termWidth, maxWidth int, color bool) []string { if p.Length < 1 { return make([]string, 0) } pos := p.History[p.Position].ScrollPosition prev := len(p.History[p.Position].WrappedContent) if termWidth != p.History[p.Position].WrapWidth || p.History[p.Position].Color != color { p.History[p.Position].WrapContent(termWidth, maxWidth, color) } now := len(p.History[p.Position].WrappedContent) if prev > now { diff := prev - now pos = pos - diff } else if prev < now { diff := now - prev pos = pos + diff if pos > now-termHeight { pos = now - termHeight } } if pos < 0 || now < termHeight-3 { pos = 0 } p.History[p.Position].ScrollPosition = pos return p.History[p.Position].WrappedContent[pos:] } func (p *Pages) CopyHistory(pos int) error { if p.Length < 2 || pos > p.Position { return fmt.Errorf("There are not enough history locations available") } if pos < 0 { pos = p.Position-1 } p.Add(p.History[pos]) return nil } //------------------------------------------------\\ // + + + F U N C T I O N S + + + \\ //--------------------------------------------------\\ // MakePages returns a Pages struct with default values func MakePages() Pages { return Pages{-1, 0, [20]Page{}} }