#!/usr/bin/python
"""Reduce the image size of pages in the comic archive"""

# Copyright 2013 ComicTagger Authors

# 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 shutil

import Image

from comictaggerlib.comicarchive import *
from comictaggerlib.settings import *

# import sys
# import os
# import tempfile
# import zipfile


# import comictaggerlib.utils


subfolder_name = "ORIGINALS"
max_height = 2000


def main():
    utils.fix_output_encoding()
    settings = ComicTaggerSettings()

    # this can only work with files with ComicRack tags
    style = MetaDataStyle.CIX

    if len(sys.argv) < 2:
        print >> sys.stderr, "Usage: {0} [comic_folder]".format(sys.argv[0])
        return

    filelist = utils.get_recursive_filelist(sys.argv[1:])

    # first make a list of all comic archive files
    comics_list = []
    max_name_len = 2
    fmt_str = u"{{0:{0}}}".format(max_name_len)
    for filename in filelist:

        ca = ComicArchive(filename, settings.rar_exe_path)
        if ca.seemsToBeAComicArchive():
            # Check the images in the file, see if we need to reduce any

            for idx in range(ca.getNumberOfPages()):
                in_data = ca.getPage(idx)
                if in_data is not None:
                    try:
                        im = Image.open(StringIO.StringIO(in_data))
                        w, h = im.size
                        if h > max_height:
                            comics_list.append(ca)

                            max_name_len = max(max_name_len, len(filename))
                            fmt_str = u"{{0:{0}}}".format(max_name_len)
                            print >> sys.stderr, fmt_str.format(filename) + "\r",
                            sys.stderr.flush()
                            break

                    except IOError:
                        # doesn't appear to be an image
                        pass

    print >> sys.stderr, fmt_str.format("") + "\r",
    print "--------------------------------------------------------------------------"
    print "Found {0} comics with over-large pages".format(len(comics_list))
    print "--------------------------------------------------------------------------"

    for item in comics_list:
        print item.path

    # now actually process those files with over-large pages
    for ca in comics_list:
        filename = ca.path
        curr_folder = os.path.dirname(filename)
        curr_subfolder = os.path.join(curr_folder, subfolder_name)

        # skip any of our generated subfolders...
        if os.path.basename(curr_folder) == subfolder_name:
            continue

        sys.stdout.write("Processing: " + filename)

        # verify that we can write to current folder
        if not os.access(filename, os.W_OK):
            print "Can't move: {0}: skipped!".format(filename)
            continue
        if not os.path.exists(curr_subfolder) and not os.access(curr_folder, os.W_OK):
            print "Can't create subfolder here: {0}: skipped!".format(filename)
            continue
        if not os.path.exists(curr_subfolder):
            os.mkdir(curr_subfolder)
        if not os.access(curr_subfolder, os.W_OK):
            print "Can't write to the subfolder here: {0}: skipped!".format(filename)
            continue

        # generate a new file with temp name
        tmp_fd, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
        os.close(tmp_fd)

        cix_md = None
        if ca.hasCIX():
            cix_md = ca.readCIX()

        try:
            zout = zipfile.ZipFile(tmp_name, "w")

            # Check the images in the file, see if we want to reduce them
            page_count = ca.getNumberOfPages()

            for idx in range(ca.getNumberOfPages()):
                name = ca.getPageName(idx)
                in_data = ca.getPage(idx)
                out_data = in_data
                if in_data is not None:
                    try:
                        im = Image.open(StringIO.StringIO(in_data))
                        w, h = im.size
                        if h > max_height:
                            # resize the image
                            hpercent = max_height / float(h)
                            wsize = int((float(w) * float(hpercent)))
                            size = (wsize, max_height)
                            im = im.resize(size, Image.ANTIALIAS)

                            output = StringIO.StringIO()
                            im.save(output, format="JPEG", quality=85)
                            out_data = output.getvalue()
                            output.close()

                    except IOError:
                        # doesn't appear to be an image
                        pass

                else:
                    # page is empty?? nothing to write
                    out_data = ""

                sys.stdout.write(".")
                sys.stdout.flush()

                # write out the new resized image
                zout.writestr(name, out_data)

            # preserve the old comment
            comment = ca.archiver.getArchiveComment()
            if comment is not None:
                zout.comment = ca.archiver.getArchiveComment()

        except Exception as e:
            print "Failure creating new archive: {0}!".format(filename)
            print e, sys.exc_info()[0]
            zout.close()
            os.unlink(tmp_name)
        else:
            zout.close()

            # Success!  Now move the files
            shutil.move(filename, curr_subfolder)
            os.rename(tmp_name, filename)
            # TODO: We might have converted a rar to a zip, and should probably change
            #  the extension, as needed.

            print "Done!".format(filename)

            # Create a new archive object for the new file, and write the old
            # CIX data, w/o page info
            if cix_md is not None:
                ca = ComicArchive(filename, settings.rar_exe_path)
                cix_md.pages = []
                ca.writeCIX(cix_md)


if __name__ == "__main__":
    main()