#!BPY
# -*- coding: utf-8 -*-
"""
Name: 'Jon3D Model (.j3dm)'
Blender: 249a
Group: 'Export'
Tooltip: 'Exports the selected object to a Jon3D Model file'
"""


# ---------------------------------------------------------------------------- #
# License                                                                      #
# ---------------------------------------------------------------------------- #

"""
Copyright © Jon Kristensen, 2010.
All rights reserved.
"""


# ---------------------------------------------------------------------------- #
# About                                                                        #
# ---------------------------------------------------------------------------- #

"""
This is script for Blender that allows exporting a Blender object to a Jon3D
Model (.j3dm) file. It contains Model-View-Controller (MVC) components through
Jon3DModelBlenderExporter{Model,View,Controller}, a class that contains the
exporter settings (Jon3DModelBlenderExporterSettings) and the actual exporter
class (Jon3DModelBlenderExporter). I have also created two simple classes to be
able to implement the Observer design pattern, Observable and Observer, which
the model and view classes are extending.

When the model, view and controller classes are initialized, the controller will
register the appropriate callbacks for the Blender windowing after which we will
request the UI to be drawn for the first time.

The GUI widgets will be drawn in a pop-up area. Whenever the user presses the
"Export" the widget area will hide and the Save File dialog will be opened in
the current window (Blender area). If no errrors or warnings are generated the
file will be exported to the specified file and the script will exit. Otherwise,
the script will display one message box for every element in the set of the
warnings and errors and return to the widgets.

TODO:

* Save vertex-based animation.
* Save skeletal-based animation.
* Ambient occlusion texture for the object.
* Read and save settings in a nicer way than using global variables.
"""


# ---------------------------------------------------------------------------- #
# Imports                                                                      #
# ---------------------------------------------------------------------------- #

import os
import bpy
import Blender
from Blender import * # Draw, BGL
# TODO: Import actual packages instead.


# ---------------------------------------------------------------------------- #
# Script metadata                                                              #
# ---------------------------------------------------------------------------- #

__author__ = "Jon Kristensen"
__url__ = ("blender", "http://jon3d.org/")
__version__ = "0.0.1.0"
__bpydoc__ = """\
Script to export a Blender object to a Jon3D Model resource. It saves
information about vertices, normals and texture coordinates.
"""


# ---------------------------------------------------------------------------- #
# Settings                                                                     #
# ---------------------------------------------------------------------------- #

globals()["IncludeTextureCoordinates"] = True
globals()["OutputDirectory"] = "/tmp"
globals()["AskBeforeOverwritingFile"] = True


# ---------------------------------------------------------------------------- #
# The classes                                                                  #
# ---------------------------------------------------------------------------- #

class Jon3DModelBlenderExporterSettings:
    IncludeTextureCoordinates = None
    OutputDirectory = None
    AskBeforeOverwritingFile = None
    
    def __init__(self):
        self.IncludeTextureCoordinates = globals()["IncludeTextureCoordinates"]
        self.OutputDirectory = globals()["OutputDirectory"]
        self.AskBeforeOverwritingFile = globals()["AskBeforeOverwritingFile"]


class Jon3DModelBlenderExporter:
    _Settings = None
    
    _Messages = []
    
    def __init__(self, Settings):
        self._Settings = Settings

    def Export(self):
        SelectedOjects = Blender.Object.GetSelected()

        if len(SelectedObjects) != 1:
            self._Messages.append("You need to select exactly one object to export.")
            return self._Messages
        else:
            pass


class Observable:
    Observers = []
    
    def AddObserver(self, Observer):
        self.Observers.append(Observer);
        
    def NotifyObservers(self):
        for Observer in self.Observers:
            Observer.Update()


class Observer:
    def Update(self):
        pass

class Jon3DModelBlenderExporterModel(Observable):
    EVENT_EXPORT = 0
    EVENT_MESSAGE_CONFIRMED = 1

    Exporter = None

    OS_POSIX = 0
    OS_WINDOWS_NT = 1
    
    OS = -1

    _Settings = Jon3DModelBlenderExporterSettings()
    _Messages = []
    CurrentMessage = None

    def __init__(self):
        self.Exporter = Jon3DModelBlenderExporter(self._Settings)
        
        self._Messages.append("Test.")
        
        if os.name == 'posix':
            self.OS = self.OS_POSIX
        elif os.name == 'nt':
            self.OS = self.OS_WINDOWS_NT
        else:
            self.OS = self.OS_POSIX
            self._Messages.append("Could not determine operating system -- assuming POSIX.")
    
    def AddMessage(self, Message):
        self._Messages.append(Message)
        self.NotifyObservers()
        
    def SetCurrentMessage(self):
        if len(self._Messages) > 0:
            self.CurrentMessage = self._Messages.pop()
        else:
            self.CurrentMessage = None
            
            
class Jon3DModelBlenderExporterView(Observer):
    _Model = None
    
    BottomXPosition = 400
    BottomYPosition = 400
    
    def __init__(self, model):
        self._Model = Model
        self._Model.AddObserver(self)
        Blender.BGL.glClearColor(0.6, 0.6, 0.6, 0.6)
        self.Update()

    def Update(self):
        print 'update'
        
        # Blender.BGL.glClearColor(0.6, 0.6, 0.6, 0.6)
        Blender.BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
        Blender.Draw.Toggle("Toggle", 1, 10, 10, 559, 299, True,"A toggle button")
        # Blender.BGL.glColor3f(1,1,1)
        # Blender.BGL.glRasterPos2i(222, 216)
        # Draw.Text("The toggle button is.")

        
        # if self._Model.CurrentMessage is None:
        #    self._Model.SetCurrentMessage()
           
        # if self._Model.CurrentMessage is not None:
        #     self.DrawMessage(self._Model.CurrentMessage)
        # else:
        #     self.DrawGUI()
        
    def DrawGUI(self):
        pass
        # Blender.BGL.glRasterPos2i(self.BottomXPosition, self.BottomYPosition)
        # Blender.Draw.UIBlock(self.DrawMenu)

    def DrawMessage(self, Message):
        # Blender.BGL.glColor3f(1,1,1)
        print Message
        # Blender.BGL.glRasterPos2i(450, 450)
        Blender.Draw.Text(Message)
        Blender.Draw.PushButton("OK", self._Model.EVENT_MESSAGE_CONFIRMED,
                                500, 500, 400, 400)
        Blender.Draw.Toggle("Clear origin",1,10,20,100,20,0,"Tooltip")
        
    def DrawMenu(self):
        pass
    

class Jon3DModelBlenderExporterController:
    _Model = None
    _View = None

    def __init__(self, Model, View):
        self._Model = Model
        self._View = View
        
        Blender.Draw.Register(self._View.Update(), self.HandleInputEvents, None) #self.HandleDrawButtonEvents)
        
    def HandleInputEvents(self, event, value):
        if event == Blender.Draw.ESCKEY:
            Blender.Draw.Exit()
        if event == Blender.Draw.SPACEKEY:
            self._View.Update()

    def HandleDrawButtonEvents(self, event):
        if event == self.EVENT_EXPORT:
            Messages = Model.Exporter.Export()
            
            for Message in Messages:
                self._Model.AddMessage(Message)

        if event == self._Model.EVENT_MESSAGE_CONFIRMED:
            self._Model.CurrentMessage = None
            Blender.Window.Redraw()


# ---------------------------------------------------------------------------- #
# Starting point                                                               #
# ---------------------------------------------------------------------------- #

Model = Jon3DModelBlenderExporterModel()
View = Jon3DModelBlenderExporterView(Model)
Controller = Jon3DModelBlenderExporterController(Model, View)
