#
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys

from color import Coloring
from command import InteractiveCommand
from git_command import GitCommand

class _ProjectList(Coloring):
  def __init__(self, gc):
    Coloring.__init__(self, gc, 'interactive')
    self.prompt = self.printer('prompt', fg='blue', attr='bold')
    self.header = self.printer('header', attr='bold')
    self.help = self.printer('help', fg='red', attr='bold')

class Stage(InteractiveCommand):
  common = True
  helpSummary = "Stage file(s) for commit"
  helpUsage = """
%prog -i [<project>...]
"""
  helpDescription = """
The '%prog' command stages files to prepare the next commit.
"""

  def _Options(self, p):
    p.add_option('-i', '--interactive',
                 dest='interactive', action='store_true',
                 help='use interactive staging')

  def Execute(self, opt, args):
    if opt.interactive:
      self._Interactive(opt, args)
    else:
      self.Usage()

  def _Interactive(self, opt, args):
    all = filter(lambda x: x.IsDirty(), self.GetProjects(args))
    if not all:
      print >>sys.stderr,'no projects have uncommitted modifications'
      return

    out = _ProjectList(self.manifest.manifestProject.config)
    while True:
      out.header('        %-20s %s', 'project', 'path')
      out.nl()

      for i in xrange(0, len(all)):
        p = all[i]
        out.write('%3d:    %-20s %s', i + 1, p.name, p.relpath + '/')
        out.nl()
      out.nl()

      out.write('%3d: (', 0)
      out.prompt('q')
      out.write('uit)')
      out.nl()

      out.prompt('project> ')
      try:
        a = sys.stdin.readline()
      except KeyboardInterrupt:
        out.nl()
        break
      if a == '':
        out.nl()
        break

      a = a.strip()
      if a.lower() in ('q', 'quit', 'exit'):
        break
      if not a:
        continue

      try:
        a_index = int(a)
      except ValueError:
        a_index = None

      if a_index is not None:
        if a_index == 0:
          break
        if 0 < a_index and a_index <= len(all):
          _AddI(all[a_index - 1])
          continue

      p = filter(lambda x: x.name == a or x.relpath == a, all)
      if len(p) == 1:
        _AddI(p[0])
        continue
    print 'Bye.'

def _AddI(project):
  p = GitCommand(project, ['add', '--interactive'], bare=False)
  p.Wait()
