#!/usr/bin/env python
#####################################################################
#
#       Author : Kushal Das
#       Copyright (c)  2007-2009 Kushal Das
#       kushal@fedoraproject.org
#
#       Copyright: See COPYING file that comes with this distribution
#
#
#####################################################################

from PyQt4 import QtCore, QtGui
from PyQt4 import uic
from mx.DateTime import now
import sys
import os
import xmlrpclib
import cPickle
import time
import tempfile
import magic

from Chotha.syntax import ResourceHighlighter
from Chotha.ImageDialogUI import ImageDialogUI
from Chotha.ConfigureWinUI import ConfigureWinUI
from lekhoneeblog.Wordpress import Wordpress
from Chotha.resource_rc import *

from PyKDE4.kdecore import ki18n, KAboutData, KCmdLineArgs
from PyKDE4.kdeui import *


__version__ = '0.7'

from Chotha.LekhoneeUI import Ui_Lekhonee

class LekhoneeApp(KApplication):
    """Main application class"""
    def __init__(self,args=None):
        appName     = "Lekhonee"
        catalog     = ""
        programName = ki18n ("Lekhonee")
        version     = __version__
        description = ki18n ("Lekhonee , a small blog client")
        license     = KAboutData.License_GPL
        copyright   = ki18n ("(c) 2007-2009 Kushal Das")
        text        = ki18n ("A Wordpress desktop client")
        homePage    = "www.fedorahosted.org/lekhonee"
        bugEmail    = "kushal@fedoraproject.org"
        self.aboutData   = KAboutData (appName, catalog, programName, version, description,\
                      license, copyright, text, homePage, bugEmail)
        KCmdLineArgs.init (sys.argv, self.aboutData)
        KApplication.__init__(self)


        #pixmap = QtGui.QPixmap(":/pixmaps/chothasplash.png")
        #self.splash = QtGui.QSplashScreen(pixmap)
        #self.splash.show()
        #QtCore.QTimer.singleShot(2000,self.splash,QtCore.SLOT("hide()"))


        self.mywindow = LekhoneeUI()
        self.mywindow.show()
        self.exec_()


class PostDetails(QtGui.QListWidgetItem):
    """ Entry """
    def __init__(self, entry,parent=None):
        QtGui.QListWidgetItem.__init__(self, entry['title'])
        self.entry = entry



class LekhoneeUI(Ui_Lekhonee, KMainWindow):
    """My class"""
    def __init__(self):
        KMainWindow.__init__(self)
        self.setupUi(self)
        #self.boldBttn.setCheckable(True)
        #self.italicBttn.setCheckable(True)
        self.stateBttn.setCheckable(True)

        self.kmenu = self.helpMenu()
        self.menubar.addMenu(self.kmenu)



        self.Server = "http://yoursite.com/xmlrpc.php"
        self.password = ""
        self.username = ""
        self.configurepath = os.path.join(os.path.expanduser("~"),'.lekhonee')
        if os.path.exists(self.configurepath):
            f = file(self.configurepath)
            data = cPickle.load(f)
            f.close()
            self.Server = data['server']
            self.username = data['username']
            try:
                self.advertisement = data['advertisement']
                if self.advertisement:
                    self.actionLekhonee_msg.setChecked(True)
                else:
                    self.actionLekhonee_msg.setChecked(False)
            except:
                print "Config file missing advertisement value"

        self.conf = ConfigureWinUI(self, start=1)
        self.conf.show()

        self.entry = None
        self.editFlag = False
        self.makeServer()
        self.selectTab(0)
        self.draftBttn.setEnabled(True)
        self.commentCheckBox.setEnabled(True)
        self.categoryList.setEnabled(True)
        self.filename = ''
        self.advertisement = True

        self.uploadframe.hide()

        self.content = ''
        self.categoriesDict = {}
        self.getCategories()
        self.highlighter = ResourceHighlighter(self.blogTxt.document())
        self.connectslots()

    def connectslots(self):
        self.connect(self.boldBttn,QtCore.SIGNAL("clicked()"),self.textBold)
        self.connect(self.italicBttn,QtCore.SIGNAL("clicked()"),self.textItalic)
        #self.connect(self.blogTxt,QtCore.SIGNAL("currentCharFormatChanged(QTextCharFormat)"),self.currentCharFormatChanged)
        self.connect(self.publishBttn,QtCore.SIGNAL("clicked()"),self.publishPost)
        self.connect(self.draftBttn,QtCore.SIGNAL("clicked()"),self.draftPost)
        self.connect(self.stateBttn,QtCore.SIGNAL("clicked()"),self.changeState)
        self.connect(self.linkBttn,QtCore.SIGNAL("clicked()"),self.insertLink)
        self.connect(self.imageBttn,QtCore.SIGNAL("clicked()"),self.insertImage)
        self.connect(self.addPageBttn,QtCore.SIGNAL("clicked()"),self.addPage)
        self.connect(self.addCategoryBttn,QtCore.SIGNAL("clicked()"),self.addCategory)
        self.connect(self.getCategoriesBttn,QtCore.SIGNAL("clicked()"),self.getCategories)
        self.connect(self.action_Save,QtCore.SIGNAL("triggered()"),self.fileSave)
        self.connect(self.action_Open,QtCore.SIGNAL("triggered()"),self.fileOpen)
        self.connect(self.actionBold,QtCore.SIGNAL("triggered()"),self.textBold)
        self.connect(self.actionItalic,QtCore.SIGNAL("triggered()"),self.textItalic)
        self.connect(self.actionUnderline,QtCore.SIGNAL("triggered()"),self.textUnderline)
        self.connect(self.actionSuperscript,QtCore.SIGNAL("triggered()"),self.textSuperscript)
        self.connect(self.actionSubscript,QtCore.SIGNAL("triggered()"),self.textSubscript)
        self.connect(self.actionInsert_link,QtCore.SIGNAL("triggered()"),self.insertLink)
        self.connect(self.actionInsert_Image,QtCore.SIGNAL("triggered()"),self.insertImage)
        self.connect(self.actionPreferences,QtCore.SIGNAL("triggered()"),self.configure)
        self.connect(self.actionLekhonee_msg,QtCore.SIGNAL("triggered()"),self.advertisement_msg)
        self.connect(self.action_Quit,QtCore.SIGNAL("triggered()"),self.exitSlot)
        self.connect(self.action_New,QtCore.SIGNAL("triggered()"),self.newPost)
        self.connect(self.actionLast_Entry,QtCore.SIGNAL("triggered()"),self.loadLastEntry)
        self.connect(self.actionUpload_File,QtCore.SIGNAL("triggered()"),self.showUploadFile)
        self.connect(self.oldPostBttn,QtCore.SIGNAL("clicked()"),self.oldPost)
        self.connect(self.uploadCancelBttn,QtCore.SIGNAL("clicked()"),self.cancelUpload)
        self.connect(self.uploadBttn,QtCore.SIGNAL("clicked()"),self.upload)
        self.connect(self.selectUploadBttn,QtCore.SIGNAL("clicked()"),self.selectUploadFile)
        self.connect(self.entryList,QtCore.SIGNAL(" itemDoubleClicked ( QListWidgetItem *)"),self.editPost)
        self.connect(self.spellCheckBox,QtCore.SIGNAL("stateChanged(int)"),self.changeSpellCheck)
        self.connect(self.conf,QtCore.SIGNAL("saved()"),self.reloadServer)

    def reloadServer(self):
        """
        Reload all info from server
        """
        self.reloadInfo()
        self.makeServer()
        self.getCategories()
        self.getEntries()

    def getEntries(self):
        """
        Reload post details
        """
        self.entryList.clear()
        entries = self.server.getEntries()
        for entry in entries:
            myentry = PostDetails(entry)
            self.entryList.addItem(myentry)

    def editPost(self, item):
        self.entry = item.entry
        self.stack.setCurrentIndex(0)
        self.oldPostBttn.setChecked(False)
        self.enableBttns()
        self.loadEntryDetails()

    def reloadInfo(self):
        """Reload server and username, password"""
        self.Server = self.conf.server
        self.username = self.conf.username
        self.password = self.conf.password
        data = {'server':self.Server,'username':self.username,'advertisement':self.advertisement}
        f = file(self.configurepath, 'w')
        cPickle.dump(data, f)
        f.close()

    def makeServer(self):
        self.server = Wordpress(self.Server, self.username, str(self.password))

    def advertisement_msg(self):
        if self.actionLekhonee_msg.isChecked():
            self.advertisement = True
        else:
            self.advertisement = False
        data = {'server':self.Server,'username':self.username,'advertisement':self.advertisement}
        f = file(self.configurepath, 'w')
        cPickle.dump(data, f)
        f.close()

    def oldPost(self):
        if self.oldPostBttn.isChecked():
            self.disableBttns()
            self.stack.setCurrentIndex(2)
        else:
            self.enableBttns()
            self.stack.setCurrentIndex(0)

    def queryClose(self):
        self.hide()
        self.disableSpellCheck()
        sys.exit()

    def showUploadFile(self):
        self.uploadframe.show()

    def cancelUpload(self):
        self.fileTxt.setText('')
        self.uploadframe.hide()

    def selectUploadFile(self):
        filename = QtGui.QFileDialog.getOpenFileName(self,'Select File for Upload','',"All Files (*)")
        if not filename:
            return
        self.fileTxt.setText(filename)

    def upload(self):
        filename = unicode(self.fileTxt.text())
        f = open(filename, "rb")
        file_data = f.read()
        f.close()
        ms = magic.open(magic.MAGIC_MIME)
        ms.load()
        type = ms.file(filename)
        ms.close()
        data = {'name':os.path.basename(filename),'type':type,'bits':xmlrpclib.Binary(file_data)}
        try:
            mes = self.server.uploadFile(data)
            cur = self.blogTxt.textCursor()
            if type.startswith('image'):
                cur.insertText('<IMG src="%s">' % (mes['url']))
            else:
                if (not cur.hasSelection()):
                    cur.insertText('<a href="%s"></a>' % (mes['url']))
                else:
                    cur.insertText('<a href="%s">%s</a>' % (mes['url'],cur.selectedText()))
        except Exception, e:
            qm = QtGui.QErrorMessage(self)
            qm.showMessage(e.faultString)

    def changeSpellCheck(self, state):
        if state == 2:
            self.enableSpellCheck()
        else:
            self.disableSpellCheck()

    def enableSpellCheck(self):
        self.blogTxt.setCheckSpellingEnabledInternal(True)

    def disableSpellCheck(self):
        self.blogTxt.setCheckSpellingEnabledInternal(False)

    def textBold(self):
        """To make a text BOLD"""
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.insertText('<strong></strong>')
        else:
            cur.insertText('<strong>%s</strong>' % (cur.selectedText()))

    def textItalic(self):
        """To make a text Italic"""
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.insertText('<i></i>')
        else:
            cur.insertText('<i>%s</i>' % (cur.selectedText()))

    def textUnderline(self):
        """To make a text Underline"""
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.insertText('<u></u>')
        else:
            cur.insertText('<u>%s</u>' % (cur.selectedText()))

    def textSuperscript(self):
        """To make a text Superscript"""
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.insertText('<sup></sup>')
        else:
            cur.insertText('<sup>%s</sup>' % (cur.selectedText()))

    def textSubscript(self):
        """To make a text Subscript"""
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.insertText('<sub></sub>')
        else:
            cur.insertText('<sub>%s</sub>' % (cur.selectedText()))

    def mergeFormatOnWordOrSelection(self,fmt):
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            cur.select(QtGui.QTextCursor.WordUnderCursor)
        cur.mergeCharFormat(fmt)
        self.blogTxt.mergeCurrentCharFormat(fmt)

    def loadLastEntry(self):
        self.entry = self.server.getLastPost()[0]
        self.loadEntryDetails()

    def loadEntryDetails(self):
        self.blogTxt.setPlainText(self.entry['description'])
        self.titleTxt.setText(self.entry['title'])
        self.tagsTxt.setText(self.entry['mt_keywords'])
        if self.entry['mt_allow_comments'] == 1:
            self.commentCheckBox.setCheckState(2)
        else:
            self.commentCheckBox.setCheckState(0)
        categories = self.entry['categories']
        self.getCategories()
        self.categoryList.setCurrentRow(self.categoryList.currentRow(),QtGui.QItemSelectionModel.Clear)
        for category in categories:
            myitems = self.categoryList.findItems(category, QtCore.Qt.MatchExactly)
            for eachitem in myitems:
                self.categoryList.setCurrentItem(eachitem, QtGui.QItemSelectionModel.Select)
        self.editFlag = True

        self.publishBttn.setText('Update')
        self.draftBttn.setEnabled(False)


    def publishPost(self):
        self.messagePost(True)

    def draftPost(self):
        self.messagePost(False)

    def changeState(self):
        if self.stateBttn.isChecked():
            self.stack.setCurrentIndex(1)
            text = """<html><head><title>%s</title></head><body>%s</body></html>"""
            text = text % (self.titleTxt.text(),self.blogTxt.toPlainText())
            text = text.replace('\n','<br>')
            self.webView.setHtml(text)
            self.disableBttns()
        else:
            self.stack.setCurrentIndex(0)
            self.enableBttns()

    def messagePost(self,publish):
        #print unicode(self.timeStamp.dateTime().toString('yyyy-mm-dd hh:mm:ss'))
        clist = self.categoryList.selectedItems()
        categories = []
        for item in clist:
            categories.append(unicode(item.text()))
        if self.commentCheckBox.checkState():
            comment = 1
        else:
            comment = 0
        #self.content = {'title':unicode(self.titleTxt.text()),'description':unicode(self.blogTxt.toHtml())[214:-14],'categories':categories,'dateCreated': unicode(self.timeStamp.dateTime().toString('yyyymmddThh:mm:ss')),'mt_allow_comments':comment}
        desc = unicode(self.blogTxt.toPlainText())
        if self.advertisement:
            mes = 'The post is brought to you by <a href="http://fedorahosted.org/lekhonee">lekhonee</a> v%s' % (__version__)
            if not self.editFlag:
                desc += '\n\n' + mes
        tags = unicode(self.tagsTxt.text()).split(",")
        if tags[0] == u'Tags':
            tags = []
        self.content = {'title':unicode(self.titleTxt.text()),'description':desc,'categories':categories,'mt_keywords':tags,'mt_allow_comments':comment}

        try:
            if not self.editFlag:
                qm = QtGui.QMessageBox.information(self, 'Done :)', self.server.post(self.content, publish))
            else:
                qm = QtGui.QMessageBox.information(self, 'Done :)', self.server.edit(self.entry['postid'],self.content, publish))
            self.clearAll()
            if self.editFlag:
                self.publishBttn.setText('Publish')
                self.draftBttn.setEnabled(True)
            self.editFlag = False
        except xmlrpclib.Fault, e:
            qm = QtGui.QErrorMessage(self)
            qm.showMessage(e.faultString)

    def disableBttns(self):
        self.boldBttn.setEnabled(False)
        self.italicBttn.setEnabled(False)
        self.linkBttn.setEnabled(False)
        self.draftBttn.setEnabled(False)
        self.publishBttn.setEnabled(False)
        self.imageBttn.setEnabled(False)

    def enableBttns(self):
        self.boldBttn.setEnabled(True)
        self.italicBttn.setEnabled(True)
        self.linkBttn.setEnabled(True)
        self.draftBttn.setEnabled(True)
        self.publishBttn.setEnabled(True)
        self.imageBttn.setEnabled(True)

    def insertLink(self):
        cur = self.blogTxt.textCursor()
        if (not cur.hasSelection()):
            qm = QtGui.QErrorMessage(self)
            qm.showMessage('Please select some text first')
        else:
            result = QtGui.QInputDialog.getText(self,'Insert the link','Link:',QtGui.QLineEdit.Normal,'http://')
            if result[1]:
                self.blogTxt.insertPlainText('<a href="%s">%s</a>' %(unicode(result[0]),unicode(cur.selectedText())))

    def getCategories(self):
        self.categoryList.clear()
        try:
            categories = self.server.getCategories()
            i = 0
            for cate in categories:
                self.categoriesDict[cate['categoryName']] = i
                i = i + 1
                self.categoryList.addItem(cate['categoryName'])
                if cate['categoryName'] == 'Uncategorized':
                    self.categoryList.setCurrentRow(self.categoryList.count() - 1 )
        except:
            self.categoryList.addItem('Uncategorized')
            self.categoryList.setCurrentRow(self.categoryList.count() - 1 )
        #We will sort it later, currently too much other work left
        #self.categoryList.sortItems()

    def fileSaveAs(self):
        fn = QtGui.QFileDialog.getSaveFileName(self, "Save blog as...",
                          '', "chotha files (*.chotha);;All Files (*)")
        if fn.isEmpty():
            return False
        self.filename = unicode(fn)
        return self.fileSave()

    def fileSave(self):
        if self.filename == '':
            return self.fileSaveAs()
        if self.commentCheckBox.checkState():
            comment = 1
        else:
            comment = 0
        content = {'title':unicode(self.titleTxt.text()),'description':unicode(self.blogTxt.toPlainText())}
        f = file(self.filename,'w')
        cPickle.dump(content,f)
        f.close()
        self.blogTxt.document().setModified(False)
        return True

    def fileOpen(self):
        fn = QtGui.QFileDialog.getOpenFileName(self,'Open saved blog...','',"chotha files (*.chotha);;All Files (*)")
        if not fn:
            return
        f = file(unicode(fn))
        data = cPickle.load(f)
        f.close()
        if self.stateBttn.isChecked():
            self.blogTxt.setHtml(data['description'])
        else:
            self.blogTxt.setPlainText(data['description'])
        self.content = data['description']
        self.titleTxt.setText(data['title'])

    def clearAll(self):
        self.blogTxt.clear()
        self.titleTxt.clear()
        self.tagsTxt.setText('Tags')
        self.getCategories()

    def insertImage(self):
        align = {'-- Not Set --': '', 'Baseline': 'baseline', 'Top': 'top', 'Middle': 'middle', 'Bottom': 'bottom', 'Text Top': 'texttop', 'Absolute Middle': 'absmiddle', 'Absolute bottom': 'abcbttom', 'Left': 'left', 'Right': 'right'}
        result = ImageDialogUI(self).getValues()
        if result[0]:
            src = result[1][0]
            desc = result[1][1]
            alignment = align[result[1][2]]
            x = result[1][3]
            y = result[1][4]
            if x ==0 or y == 0:
                if alignment == '':
                    imgString = '<img src="%s" title="%s" alt="%s" />' % (src, desc, desc)
                else:
                    imgString = '<img src="%s" title="%s" alt="%s" align="%s" />' % (src, desc, desc, alignment)
            else:
                if alignment == '':
                    imgString = '<img src="%s" title="%s" alt="%s" height="%s" width="%s" />' % (src, desc, desc, x, y)
                else:
                    imgString = '<img src="%s" title="%s" alt="%s" align="%s" height="%s" width="%s" />' % (src, desc, desc, alignment, x, y)
            self.blogTxt.insertPlainText(imgString)

    def previewFF(self):
        mes = unicode(self.blogTxt.toPlainText())
        f, name = tempfile.mkstemp()
        #f = os.fdopen(f)
        name += '.html'
        f = file(name,'w')
        f.write(mes)
        f.close()
        os.system('firefox -remote "openurl(file://%s,new-tab)"' % name)

    def previewKq(self):
        mes = unicode(self.blogTxt.toPlainText())
        f = file(os.path.join('/tmp','chothatmp.html'),'w')
        f.write(mes)
        f.close()
        os.system('konqueror file://%s' % (os.path.join('/tmp','chothatmp.html')))

    def configure(self):
        self.conf.show()

    #def previousEntries(self):
        #self.getCategories()
        #oldEntries = OldEntryDialogUI(self, self.server, self.username, self.password)

    def exitSlot(self):
        sys.exit(0)

    def newPost(self):
        self.blogTxt.setPlainText('')
        self.titleTxt.clear()
        self.tagsTxt.setText('Tags')
        if self.editFlag:
            self.publishBttn.setText('Publish')
            self.draftBttn.setEnabled(True)
            self.editFlag = False

    def showAbout(self):
        self.about = AboutChothaUI(self)

    def selectTab(self, index):
        """Select the proper tab and disable the other tabs"""
        for i in range(0,2):
            self.serverTabs.setTabEnabled(i,False)
        self.serverTabs.setCurrentIndex(index)
        self.serverTabs.setTabEnabled(index,True)

    def getMusic(self):
        """Get the current track name from Amarok"""
        try:
            musicname = os.popen('dcop amarok player nowPlaying').readlines()
        except:
            musicname.append("call failed")
        if musicname[0] == "call failed":
            self.musicTxt.setText('No Amarok')
        else:
            self.musicTxt.setText(musicname[0][:-1])

    def addCategory(self):
        """This will add the new category"""
        newcategory = unicode(self.addCategoryTxt.text())
        self.server.addCategory(newcategory)
        self.categoryList.addItem(newcategory)
        self.categoryList.setCurrentRow(self.categoryList.count() - 1 )


    def addPage(self):
        """Add a new page in the server"""
        desc = unicode(self.blogTxt.toPlainText())
        self.content = {'title':unicode(self.titleTxt.text()),'description':desc}
        try:
            self.server.addPage(self.content, True)
            self.newPost()
        except:
            print "Add page failed"

if __name__ == '__main__':
    kApp = LekhoneeApp(sys.argv)
