<commit_before>package swarm

import (
	"fmt"
	"sync"

	"github.com/docker/docker/api/types/swarm"
	gizaktermui "github.com/gizak/termui"
	"github.com/moncho/dry/appui"
	"github.com/moncho/dry/docker"
	"github.com/moncho/dry/ui"
	"github.com/moncho/dry/ui/termui"
)

//ServiceTasksWidget shows a service's task information
type ServiceTasksWidget struct {
	swarmClient          docker.SwarmAPI
	service              *swarm.Service
	tasks                []*TaskRow
	header               *termui.TableHeader
	info                 *ServiceInfoWidget
	tableTitle           termui.SizableBufferer
	selectedIndex        int
	offset               int
	x, y                 int
	height, width        int
	startIndex, endIndex int
	sync.RWMutex
}

//NewServiceTasksWidget creates a TasksWidget
func NewServiceTasksWidget(swarmClient docker.SwarmAPI, y int) *ServiceTasksWidget {
	w := &ServiceTasksWidget{
		swarmClient:   swarmClient,
		header:        defaultTasksTableHeader,
		selectedIndex: 0,
		offset:        0,
		x:             0,
		y:             y,
		width:         ui.ActiveScreen.Dimensions.Width}
	return w
}

//PrepareToRender prepares this widget for rendering
func (s *ServiceTasksWidget) PrepareToRender(serviceID string) {
	s.Lock()
	defer s.Unlock()
	if service, err := s.swarmClient.Service(serviceID); err == nil {
		serviceInfo := NewServiceInfoWidget(s.swarmClient, service, s.y)
		s.height = appui.MainScreenAvailableHeight() - serviceInfo.GetHeight()
		s.service = service
		s.info = serviceInfo

		if tasks, err := s.swarmClient.ServiceTasks(serviceID); err == nil {
			s.tableTitle = createTableTitle(serviceInfo.serviceName, len(tasks))
			for _, task := range tasks {
				s.tasks = append(s.tasks, NewTaskRow(s.swarmClient, task, s.header))
			}
		}
		s.align()
	}

}

//Align aligns rows
func (s *ServiceTasksWidget) align() {
	x := s.x
	width := s.width

	s.info.SetX(x)
	s.info.SetWidth(width)
	s.tableTitle.SetX(x)
	s.tableTitle.SetWidth(width)
	s.header.SetWidth(width)
	s.header.SetX(x)

	for _, n := range s.tasks {
		n.SetX(x)
		n.SetWidth(width)
	}
}

//Buffer returns the content of this widget as a termui.Buffer
func (s *ServiceTasksWidget) Buffer() gizaktermui.Buffer {
	s.Lock()
	defer s.Unlock()
	y := s.y

	buf := gizaktermui.NewBuffer()
	if s.info != nil {
		buf.Merge(s.info.Buffer())
		y += s.info.GetHeight()
	}
	s.tableTitle.SetY(y)
	buf.Merge(s.tableTitle.Buffer())
	y += s.tableTitle.GetHeight()
	s.header.SetY(y)
	buf.Merge(s.header.Buffer())
	y += s.header.GetHeight()

	s.highlightSelectedRow()
	for _, node := range s.visibleRows() {
		node.SetY(y)
		node.Height = 1
		y += node.GetHeight()
		buf.Merge(node.Buffer())
	}

	return buf
}

//RowCount returns the number of rowns of this widget.
func (s *ServiceTasksWidget) RowCount() int {
	return len(s.tasks)
}
func (s *ServiceTasksWidget) highlightSelectedRow() {
	if s.RowCount() == 0 {
		return
	}
	index := ui.ActiveScreen.Cursor.Position()
	if index > s.RowCount() {
		index = s.RowCount() - 1
	}
	s.tasks[s.selectedIndex].NotHighlighted()
	s.selectedIndex = index
	s.tasks[s.selectedIndex].Highlighted()
}

//OnEvent runs the given command
func (s *ServiceTasksWidget) OnEvent(event appui.EventCommand) error {<commit_msg>Minor fixes<commit_after>package swarm

import (
	"fmt"
	"sync"

	"github.com/docker/docker/api/types/swarm"
	gizaktermui "github.com/gizak/termui"
	"github.com/moncho/dry/appui"
	"github.com/moncho/dry/docker"
	"github.com/moncho/dry/ui"
	"github.com/moncho/dry/ui/termui"
)

//ServiceTasksWidget shows a service's task information
type ServiceTasksWidget struct {
	swarmClient          docker.SwarmAPI
	service              *swarm.Service
	tasks                []*TaskRow
	header               *termui.TableHeader
	info                 *ServiceInfoWidget
	tableTitle           termui.SizableBufferer
	selectedIndex        int
	offset               int
	x, y                 int
	height, width        int
	startIndex, endIndex int
	sync.RWMutex
}

//NewServiceTasksWidget creates a TasksWidget
func NewServiceTasksWidget(swarmClient docker.SwarmAPI, y int) *ServiceTasksWidget {
	w := &ServiceTasksWidget{
		swarmClient:   swarmClient,
		header:        defaultTasksTableHeader,
		selectedIndex: 0,
		offset:        0,
		x:             0,
		y:             y,
		width:         ui.ActiveScreen.Dimensions.Width}
	return w
}

//PrepareToRender prepares this widget for rendering
func (s *ServiceTasksWidget) PrepareToRender(serviceID string) {
	s.Lock()
	defer s.Unlock()
	if service, err := s.swarmClient.Service(serviceID); err == nil {
		serviceInfo := NewServiceInfoWidget(s.swarmClient, service, s.y)
		s.height = appui.MainScreenAvailableHeight() - serviceInfo.GetHeight()
		s.service = service
		s.info = serviceInfo

		if tasks, err := s.swarmClient.ServiceTasks(serviceID); err == nil {
			s.tableTitle = createTableTitle(serviceInfo.serviceName, len(tasks))
			var rows []*TaskRow
			for _, task := range tasks {
				rows = append(rows, NewTaskRow(s.swarmClient, task, s.header))
			}
			s.tasks = rows
		}
		s.align()
	}

}

//Align aligns rows
func (s *ServiceTasksWidget) align() {
	x := s.x
	width := s.width

	s.info.SetX(x)
	s.info.SetWidth(width)
	s.tableTitle.SetX(x)
	s.tableTitle.SetWidth(width)
	s.header.SetWidth(width)
	s.header.SetX(x)

	for _, n := range s.tasks {
		n.SetX(x)
		n.SetWidth(width)
	}
}

//Buffer returns the content of this widget as a termui.Buffer
func (s *ServiceTasksWidget) Buffer() gizaktermui.Buffer {
	s.Lock()
	defer s.Unlock()
	y := s.y

	buf := gizaktermui.NewBuffer()
	if s.info != nil {
		buf.Merge(s.info.Buffer())
		y += s.info.GetHeight()
	}
	s.tableTitle.SetY(y)
	buf.Merge(s.tableTitle.Buffer())
	y += s.tableTitle.GetHeight()
	s.header.SetY(y)
	buf.Merge(s.header.Buffer())
	y += s.header.GetHeight()

	s.highlightSelectedRow()
	for _, node := range s.visibleRows() {
		node.SetY(y)
		node.Height = 1
		y += node.GetHeight()
		buf.Merge(node.Buffer())
	}

	return buf
}

//RowCount returns the number of rowns of this widget.
func (s *ServiceTasksWidget) RowCount() int {
	return len(s.tasks)
}
func (s *ServiceTasksWidget) highlightSelectedRow() {
	count := s.RowCount()
	if count == 0 {
		return
	}
	index := ui.ActiveScreen.Cursor.Position()
	if index > count {
		index = count - 1
	}
	if s.selectedIndex < count && s.tasks[s.selectedIndex] != nil {
		s.tasks[s.selectedIndex].NotHighlighted()
	}
	s.selectedIndex = index
	s.tasks[s.selectedIndex].Highlighted()
}

//OnEvent runs the given command
func (s *ServiceTasksWidget) OnEvent(event appui.EventCommand) error {
{'fraction_non_alphanumeric': 0.12652625152625152, 'fraction_numerical': 0.0018315018315018315, 'mean_word_length': 3.257959714100065, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '94459', 'n_tokens_mistral': 2426, 'n_tokens_neox': 2319, 'n_words': 501}