# -*- encoding: utf-8 -*-
import collections
from abjad.tools import indicatortools
from abjad.tools import instrumenttools
from abjad.tools import scoretools
from abjad.tools.abctools.AbjadObject import AbjadObject
from abjad.tools.topleveltools import attach


class StringOrchestraScoreTemplate(AbjadObject):
    '''String orchestra score template.

    ::

        >>> template = templatetools.StringOrchestraScoreTemplate(
        ...     violin_count=6,
        ...     viola_count=4,
        ...     cello_count=3,
        ...     contrabass_count=2,
        ...     )
        >>> score = template()

    ::

        >>> score
        <Score-"String Orchestra Score"<<4>>>

    ..  doctest::

        >>> print(format(score))
        \context Score = "String Orchestra Score" <<
            \context StaffGroup = "Violin Staff Group" <<
                \context Staff = "Violin 1 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 1 }
                    \set Staff.shortInstrumentName = \markup { Vln. 1 }
                    \context Voice = "Violin 1 Voice" {
                    }
                }
                \context Staff = "Violin 2 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 2 }
                    \set Staff.shortInstrumentName = \markup { Vln. 2 }
                    \context Voice = "Violin 2 Voice" {
                    }
                }
                \context Staff = "Violin 3 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 3 }
                    \set Staff.shortInstrumentName = \markup { Vln. 3 }
                    \context Voice = "Violin 3 Voice" {
                    }
                }
                \context Staff = "Violin 4 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 4 }
                    \set Staff.shortInstrumentName = \markup { Vln. 4 }
                    \context Voice = "Violin 4 Voice" {
                    }
                }
                \context Staff = "Violin 5 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 5 }
                    \set Staff.shortInstrumentName = \markup { Vln. 5 }
                    \context Voice = "Violin 5 Voice" {
                    }
                }
                \context Staff = "Violin 6 Staff" {
                    \clef "treble"
                    \set Staff.instrumentName = \markup { Violin 6 }
                    \set Staff.shortInstrumentName = \markup { Vln. 6 }
                    \context Voice = "Violin 6 Voice" {
                    }
                }
            >>
            \context StaffGroup = "Viola Staff Group" <<
                \context Staff = "Viola 1 Staff" {
                    \clef "alto"
                    \set Staff.instrumentName = \markup { Viola 1 }
                    \set Staff.shortInstrumentName = \markup { Vla. 1 }
                    \context Voice = "Viola 1 Voice" {
                    }
                }
                \context Staff = "Viola 2 Staff" {
                    \clef "alto"
                    \set Staff.instrumentName = \markup { Viola 2 }
                    \set Staff.shortInstrumentName = \markup { Vla. 2 }
                    \context Voice = "Viola 2 Voice" {
                    }
                }
                \context Staff = "Viola 3 Staff" {
                    \clef "alto"
                    \set Staff.instrumentName = \markup { Viola 3 }
                    \set Staff.shortInstrumentName = \markup { Vla. 3 }
                    \context Voice = "Viola 3 Voice" {
                    }
                }
                \context Staff = "Viola 4 Staff" {
                    \clef "alto"
                    \set Staff.instrumentName = \markup { Viola 4 }
                    \set Staff.shortInstrumentName = \markup { Vla. 4 }
                    \context Voice = "Viola 4 Voice" {
                    }
                }
            >>
            \context StaffGroup = "Cello Staff Group" <<
                \context Staff = "Cello 1 Staff" {
                    \clef "bass"
                    \set Staff.instrumentName = \markup { Cello 1 }
                    \set Staff.shortInstrumentName = \markup { Vc. 1 }
                    \context Voice = "Cello 1 Voice" {
                    }
                }
                \context Staff = "Cello 2 Staff" {
                    \clef "bass"
                    \set Staff.instrumentName = \markup { Cello 2 }
                    \set Staff.shortInstrumentName = \markup { Vc. 2 }
                    \context Voice = "Cello 2 Voice" {
                    }
                }
                \context Staff = "Cello 3 Staff" {
                    \clef "bass"
                    \set Staff.instrumentName = \markup { Cello 3 }
                    \set Staff.shortInstrumentName = \markup { Vc. 3 }
                    \context Voice = "Cello 3 Voice" {
                    }
                }
            >>
            \context StaffGroup = "Contrabass Staff Group" <<
                \context Staff = "Contrabass 1 Staff" {
                    \clef "bass_8"
                    \set Staff.instrumentName = \markup { Contrabass 1 }
                    \set Staff.shortInstrumentName = \markup { Cb. 1 }
                    \context Voice = "Contrabass 1 Voice" {
                    }
                }
                \context Staff = "Contrabass 2 Staff" {
                    \clef "bass_8"
                    \set Staff.instrumentName = \markup { Contrabass 2 }
                    \set Staff.shortInstrumentName = \markup { Cb. 2 }
                    \context Voice = "Contrabass 2 Voice" {
                    }
                }
            >>
        >>

    Returns score template.
    '''

    ### INITIALIZER ###

    def __init__(
        self,
        violin_count=6,
        viola_count=4,
        cello_count=3,
        contrabass_count=2,
        ):
        assert 0 <= violin_count
        assert 0 <= viola_count
        assert 0 <= cello_count
        assert 0 <= contrabass_count
        self._violin_count = int(violin_count)
        self._viola_count = int(viola_count)
        self._cello_count = int(cello_count)
        self._contrabass_count = int(contrabass_count)

    ### SPECIAL METHODS ###

    def __call__(self):
        r'''Calls string orchestra template.

        Returns score.
        '''

        string_orchestra_score = scoretools.Score(
            name='String Orchestra Score',
            )

        if self.violin_count:
            violin_staff_group = scoretools.StaffGroup(
                name='Violin Staff Group',
                )
            for i in range(1, self.violin_count + 1):
                violin_voice = scoretools.Voice(
                    name='Violin {} Voice'.format(i),
                    )
                violin_staff = scoretools.Staff(
                    [violin_voice], name='Violin {} Staff'.format(i))
                clef = indicatortools.Clef('treble')
                attach(clef, violin_staff)
                violin = instrumenttools.Violin(
                    instrument_name_markup='Violin {}'.format(i),
                    short_instrument_name_markup='Vln. {}'.format(i),
                    )
                attach(violin, violin_staff)
                violin_staff_group.append(violin_staff)
            string_orchestra_score.append(violin_staff_group)

        if self.viola_count:
            viola_staff_group = scoretools.StaffGroup(
                name='Viola Staff Group',
                )
            for i in range(1, self.viola_count + 1):
                viola_voice = scoretools.Voice(
                    name='Viola {} Voice'.format(i),
                    )
                viola_staff = scoretools.Staff(
                    [viola_voice], name='Viola {} Staff'.format(i))
                clef = indicatortools.Clef('alto')
                attach(clef, viola_staff)
                viola = instrumenttools.Viola(
                    instrument_name_markup='Viola {}'.format(i),
                    short_instrument_name_markup='Vla. {}'.format(i),
                    )
                attach(viola, viola_staff)
                viola_staff_group.append(viola_staff)
            string_orchestra_score.append(viola_staff_group)

        if self.cello_count:
            cello_staff_group = scoretools.StaffGroup(
                name='Cello Staff Group',
                )
            for i in range(1, self.cello_count + 1):
                cello_voice = scoretools.Voice(
                    name='Cello {} Voice'.format(i),
                    )
                cello_staff = scoretools.Staff(
                    [cello_voice], name='Cello {} Staff'.format(i))
                clef = indicatortools.Clef('bass')
                attach(clef, cello_staff)
                cello = instrumenttools.Cello(
                    instrument_name_markup='Cello {}'.format(i),
                    short_instrument_name_markup='Vc. {}'.format(i),
                    )
                attach(cello, cello_staff)
                cello_staff_group.append(cello_staff)
            string_orchestra_score.append(cello_staff_group)

        if self.contrabass_count:
            contrabass_staff_group = scoretools.StaffGroup(
                name='Contrabass Staff Group',
                )
            for i in range(1, self.contrabass_count + 1):
                contrabass_voice = scoretools.Voice(
                    name='Contrabass {} Voice'.format(i),
                    )
                contrabass_staff = scoretools.Staff(
                    [contrabass_voice], name='Contrabass {} Staff'.format(i))
                clef = indicatortools.Clef('bass_8')
                attach(clef, contrabass_staff)
                contrabass = instrumenttools.Contrabass(
                    instrument_name_markup='Contrabass {}'.format(i),
                    short_instrument_name_markup='Cb. {}'.format(i),
                    )
                attach(contrabass, contrabass_staff)
                contrabass_staff_group.append(contrabass_staff)
            string_orchestra_score.append(contrabass_staff_group)

        # return string quartet score
        return string_orchestra_score

    ### PUBLIC PROPERTIES ###

    @property
    def cello_count(self):
        r'''Number of cellos in string orchestra.

        Returns nonnegative integer.
        '''
        return self._cello_count

    @property
    def contrabass_count(self):
        r'''Number of contrabasses in string orchestra.

        Returns nonnegative integer.
        '''
        return self._contrabass_count

    @property
    def viola_count(self):
        r'''Number of violas in string orcestra.

        Returns nonnegative integer.
        '''
        return self._viola_count

    @property
    def violin_count(self):
        r'''Number of violins in string orchestra.

        Returns nonnegative integer.
        '''
        return self._violin_count
