#!/usr/bin/env kross
# -*- coding: utf-8 -*-
import Parley
import socket
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4 import uic
# for localization (i18n)
from PyKDE4.kdecore import *
from PyKDE4.kdeui import KIcon
from PyKDE4.kdeui import KDialog
from PyKDE4.kdeui import KMessageBox

from os import path
from os import mkdir
import urllib2
import urllib
from sgmllib import SGMLParser


# TODO
# + Fetch more images (get the next results page)
# + Resize images before saving (to take less space)
# + comment out the code!
# + improve getIdentifier function (maybe by adding a new C++ function)
# + add "Alert" message box when no translation was selected

#GUI
uiFile = "google_images.ui"

#dialog class (loads google_images.ui)
class ImageDialog(KDialog):
  def __init__(self, translations):
    KDialog.__init__(self)

    self.w = None
    #look for the uiFile in plugin dirs and get the first occurence of it
    for plugindir in Parley.pluginDirs():
      if path.exists(plugindir+uiFile):
        (ImageWidget, widget) = uic.loadUiType(plugindir+uiFile)
        self.w = ImageWidget()
        self.w.setupUi(self.mainWidget())
        break

    if self.w is None:
        KMessageBox.error(None, i18n("Error: ui file not found.\nCheck your installation."), i18n("Fetch Image"))
        return

    self.translation = translations[0]

    #member variables
    self.word = self.translation.text
    self.locale = locale(getIdentifier(self.translation))
    
    self.w.nextButton.setIcon(KIcon("go-next"))
    self.w.previousButton.setIcon(KIcon("go-previous"))
    self.w.searchButton.setIcon(KIcon("edit-find"))

    # Connect signals
    self.connect(self.w.nextButton, QtCore.SIGNAL("clicked()"),self.nextImage)
    self.connect(self.w.previousButton, QtCore.SIGNAL("clicked()"),self.previousImage)
    self.connect(self.w.searchButton, QtCore.SIGNAL("clicked()"),self.searchBtnClicked)
    self.connect(self.w.freeImageCheckBox, QtCore.SIGNAL("clicked()"),self.searchBtnClicked)
    self.connect(self, QtCore.SIGNAL("okClicked()"),self.okBtnClicked)
    self.connect(self, QtCore.SIGNAL("cancelClicked()"),self.cancelBtnClicked)
    
    #set search text
    self.w.searchEdit.setText(self.word)
    
    #display image
    self.searchBtnClicked()

    
  def showImage(self,url):
    #pixmap = self.getPixmap("http://www.tuning-blog.net/wp-content/uploads/2007/05/audittclubsportquattro1.jpg")
    pixmap = self.getPixmap(url)
    if pixmap:
        p = pixmap.scaledToWidth(self.width()-10)
        if p.height() > self.height()-100:
            p = p.scaledToHeight(self.height()-100)
        self.w.imageLabel.setPixmap(p)
        return True
    else:
      return False


  #Returns a QPixmap from the given http url or None if url is invalid
  def getPixmap(self,url):
    pixmap = QtGui.QPixmap()
    try:
      img = urllib2.urlopen(url)
      imgdata = img.read()
      pixmap.loadFromData(imgdata);
      return pixmap
    except:
      print "Image not found"
      return None
    

  def nextImage(self):
    self.img_index += 1
    if self.img_index < len(self.images):
      print self.images[self.img_index]
      if not self.showImage(self.images[self.img_index]):
        self.nextImage()

  def previousImage(self):
    self.img_index -= 1
    if self.img_index >= 0:
      print self.images[self.img_index]
      if not self.showImage(self.images[self.img_index]):
        self.previousImage()

  def searchBtnClicked(self):
    data = self.fetchData()
    self.images = getImageUrls(data)
    #display the first image (a small hack)
    self.img_index = -1
    self.nextImage()

  def okBtnClicked(self):
    filesdir = getFilesDir()
    if not path.exists(filesdir):
        mkdir(filesdir)
    url = self.images[self.img_index]
    [u,img_name] = url.rsplit("/",1)
    [name,ext] = img_name.rsplit(".",1)
    
    #get a unique file name
    if path.exists(filesdir+"/"+name+"."+ext):
        c = 1
        while path.exists(filesdir+"/"+name+"-"+str(c)+"."+ext):
            c += 1
        fn = filesdir+"/"+name+"-"+str(c)+"."+ext
    else:
        fn = filesdir+"/"+name+"."+ext
        
    print fn
      
    self.w.imageLabel.pixmap().save(fn)
    self.translation.imageUrl = fn
    self.close()

  def cancelBtnClicked(self):
    self.close()


  # fetches the html document for the given word and language pair
  def fetchData(self):
    timeout = 10.0
    socket.setdefaulttimeout(timeout)

    url = "http://images.google.com/images"
    user_agent = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072820 Firefox/3.0.1'
    #params = [("gbv","2"),("hl",lang),("safe","active"),("q",word),("sa","2"),("btnG","Bilder-Suche")]
    params = {"q":self.w.searchEdit.text(), "hl":self.locale, "safe":"active"}
    if self.w.freeImageCheckBox.isChecked():
      params["as_rights"]="(cc_publicdomain|cc_attribute|cc_sharealike|cc_noncommercial|cc_nonderived)"

    headrs = { 'User-Agent' : user_agent }
    request_url = url + "?" + urllib.urlencode(params)
    req = urllib2.Request(url = request_url, headers=headrs)
    
    try:
      response = urllib2.urlopen(req)
      #print response.read()
      return response.read()
    except:
      #in case of error not to return incompleted results
      print "error on fetching online data"
      return ""


#FUNCTIONS


#parses the data (html) and returns all the links to images
def getImageUrls(data):
  print "Parsing data"
  imageurls = []
  imageextensions=[".jpg",".png",".bmp",".jif"]
  print data
  for d in data.split('"'):
    if d.startswith('http://'):
      
      if (d[-4:]).lower() in imageextensions:
        print d
        imageurls.append(d)
  return imageurls
  

#downloads image from the url given and returns the data (array of chars)
def downloadImage(url):
  img = urllib2.urlopen(url)
  imgdata = img.read()
  return imgdata

#get the identifier of the given translation (see Scripting::Translation)
def getIdentifier(trans):
  sel_entries = Parley.selectedEntries()
  for entry in sel_entries:
    #print "entry",entry
    for i in entry.translationIndices():
      #print "index",i
      if entry.translation(i).text == trans.text:
        return Parley.doc.identifier(i).locale

#corrects the difference between the locale names of Parley and the google dictionary
def locale(lang):
  if lang == "en_US":
    return "en"
  if lang == "zh_TW":
    return "zh-TW"
  if lang == "zh_HK":
    return "zh-HK"
  if lang == "zh_CN":
    return "zh-CN"

  return lang

#Get the string that describes the _files directory next to the Parley document
def getFilesDir():
    filepath = Parley.doc.url
    #print path.dirname(filepath)
    p,f = path.split(filepath)
    [name,ext] = f.rsplit(".",1)
    #print f.rsplit(".",1)
    filesdir = p+"/"+name+"_files"
    return filesdir


#ACTION FUNCTION

#method called by clicking "Fetch image" in the Scripts menu
def fetchImage():
  print "fetching image"
  translations = Parley.selectedTranslations()
  if len(translations) > 0:
    m = ImageDialog(translations)
    m.exec_()

  else:
    KMessageBox.error(None, i18n("No Selection:\nSelect a word to fetch an image for it"), i18n("Fetch Image"))


#SCRIPT MENU

#create a new action for the Scripts menu (action1)
action1 = Parley.newAction("example_action1", i18n("Fetch Image"))
action1.statusTip = str(i18n("Fetches an image for the selected translation"))
Parley.connect(action1,"triggered()",fetchImage)

