text:
<?php namespace Citrino\Contentesimporter\Models;

use File as FileExt;
use Config;
use Flash;
use Cms\Classes\ComponentBase;
use Model;
use Exception;
use Redirect;
use Session;
use Backend\Classes\FormField;
use ValidationException;

use Storage;
use System\Models\File;

use Citrino\Contentesimporter\Classes\htmlExporter;

use RainLab\Pages\Classes\Controller;
/**
 * Model
 */

define('DS',DIRECTORY_SEPARATOR);

class Import extends Model
{

    /*
     * Validation
     */
    use \October\Rain\Database\Traits\Validation;

    public $rules = [
    	'title' => 'required',
    	'slug' => 'required|unique:citrino_contentesimporter_imports,slug,citrino.contentesimporter::lang.import.slug_exerption'
    ];

    /*
     * Disable timestamps by default.
     * Remove this line if timestamps are defined in the database table.
     */
    public $timestamps = false;

    /**
     * @var string The database table used by the model.
     */
    public $table = 'citrino_contentesimporter_imports';

    public $attachOne = [ 'filegen' => ['System\Models\File'] ];

	public $attachMany = [ 'images' => ['System\Models\File', 'order' => 'sort_order'] ];

    public function beforeFetch(){
    	//var_dump($this->getLayoutOptionsList());
    }

	public function getLayoutOptions($keyValue = null)
	{
	    $layouts_directory_path = base_path()."/themes/".Config::get("cms.activeTheme",'')."/layouts";
		$layouts = FileExt::files($layouts_directory_path);
		$options = [];
		foreach ($layouts as $key=>$value) {
            $value = basename($value,'.htm');
			$options[$value] = $value;
		}

		return $options;

	}
    public function afterValidate()
    {
/*
        $attributes = $this->getAttributes();
        var_dump($attributes);
        */
    }

    public function beforeSave(){

		$attributes = $this->getAttributes();

        $slug = $attributes['slug'];
        $title = $attributes['title'];
        $override = $attributes['override'];

        $chapter = $this->fileGetContent();
        $local_path = DS.'Rapporto';

        $chapter_directory_name = "Chapter_".substr($slug,1);
        $content_directory_path = base_path().DS."themes".DS.Config::get("cms.activeTheme",'').DS."content";
        $page_directory_path = base_path().DS."themes".DS.Config::get("cms.activeTheme",'').DS."pages".$local_path;
        $chapter_directory_path = $content_directory_path.DS.$chapter_directory_name;
        $page_full = $page_directory_path.DS.'Chapter_'.substr($slug,1).'.htm';

        //page Content
        $meta = array('robot_index'=>'index','robot_follow'=>'follow');
        $pageContent = $this->pageGeneration($chapter, $meta);

        if(!FileExt::isDirectory($chapter_directory_path)){
            $out = FileExt::makeDirectory($chapter_directory_path);
            foreach ($chapter['paragraphs'][0] as $key => $paragraph) {
                if (array_key_exists('title',$paragraph)){
                    FileExt::put($chapter_directory_path.DS.'paragraph'.($key+1).'.htm', $paragraph['plaintext']);
                }
            }
            // write the page files
            if(!FileExt::exists($page_full)){
                FileExt::put($page_full,$pageContent);
            }
            //go
            Flash::success('Il Capitolo '.$chapter['title'].' é stato creato correttamente!');
        }else{

            if($override==0){

                throw new ValidationException(['override' => "Il Capitolo ".$title." esite già, se vuoi aggiornarlo spunta l'opzione Override!"]);

            }else{

                FileExt::deleteDirectory($chapter_directory_path,true);

                foreach ($chapter['paragraphs'][0] as $key => $paragraph) {
                    if (array_key_exists('title',$paragraph)){
                        FileExt::put($chapter_directory_path.DS.'paragraph'.($key+1).'.htm', $paragraph['plaintext']);
                    }
                }
                if(!FileExt::exists($page_full)){
                    FileExt::put($page_full,$pageContent);
                }
                Flash::success('Il Capitolo '.$title.' é stato aggiornato correttamente!');

        	}

    	}

	}

	public function filterFields($fields, $context = null){

		if($fields->filegen->value == -1){

			$chapter = $this->fileGetContent();

			$fields->title->value = $chapter['title'];
			$fields->import_contents->hidden = false;

	        $chapter_struct = 'il contenuto del capitolo: '.$chapter['title'].'
';

	        foreach ($chapter['paragraphs'][0] as $key => $paragraph) {
	        	if (array_key_exists('title',$paragraph)){
	        	 	 $chapter_struct .= nl2br(e('-  '.$paragraph['title'])).'
';
	        	}
	        }

			$fields->import_contents->value = $chapter_struct ;

			$fields->slug->value = '\'.str_slug( $chapter['title'], "-");
		}

        //force ovverride to stay off

        $fields->override->value = 0;

	}

	public function beforeDelete(){

		$local_path = DS.'Rapporto';

		$chapter_directory_name = "Chapter_".substr($this->slug,1);
        $content_directory_path = base_path().DS."themes".DS.Config::get("cms.activeTheme",'').DS."content";
        $page_directory_path = base_path().DS."themes".DS.Config::get("cms.activeTheme",'').DS."pages".$local_path;
        $chapter_directory_path = $content_directory_path.DS.$chapter_directory_name;
        $page_full = $page_directory_path.DS.'Chapter_'.substr($this->slug,1).'.htm';

		if(FileExt::isDirectory($chapter_directory_path)){
			FileExt::deleteDirectory($chapter_directory_path,true);
    	}
    	if(FileExt::isFile($page_full)){
	        FileExt::delete($page_full);
    	}

	}

	public function fileGetContent(){

		$sessionKey = \Input::get('_session_key');

        // returns the latest file uploaded in the current session
        // is this a reliable approach?
        $file = $this
            ->filegen()
            ->withDeferred($sessionKey)
            ->latest()
            ->first();

        $filename = $file->getLocalPath();

        $htmlExporter = new htmlExporter;
        $images = $this->getImageAttribute();

        $chapter = $htmlExporter->generateParagraphs($filename, $images );

		return $chapter;

	}

	public function getImageAttribute(){
		$sessionKey = \Input::get('_session_key');
		$img = $this->images()->withDeferred($sessionKey)->get();

		$images = [];
		foreach ($img as $key => $image) {
			$images[$image->getFileName()] = $image->getPath();
		}

		return $images;

	}

	public function pageGeneration($chapter,$meta = array('robot_index'=>'index','robot_follow'=>'follow')){

		$title = $chapter['title'];
		$slug = $this->slug;
		$layout = $this->layout;
		if(!$layout){$layout = 'defalut';};
		$page = '
title = "'.$title.'"
url = "/Rapporto/'.substr($slug, 1).'"
layout = "'.$layout.'"
is_hidden = 0
robot_index = "'.$meta['robot_index'].'"
robot_follow =  "'.$meta['robot_follow'].'"
==
{% partial "chapterRender" capitolo="'.substr($slug, 1).'" title="'.$title.'" %}';

		return $page;

	}

}


text:
layout: archive
title: "Latest Posts in *teachffenglish*"
excerpt: "凡凡-英语教案"

---

<div class="tiles">
{% for post in site.categories.teachffenglish %}
	{% include post-grid.html %}
{% endfor %}
</div><!-- /.tiles -->

redpajama_set_name: RedPajamaGithub


text:
import matplotlib.pyplot as plt
import openml
import csv

from collections import OrderedDict

x_axis_feature = 'NumberOfInstances'
x_axis_label = 'Number of Data Points'

y_axis_feature = 'NumberOfFeatures'
y_axis_label = 'Number of Features'

type = 'rbf'
if type == 'rf':
    results_file = '/home/vanrijn/experiments/archive/20170908/rf/ranks.csv'
    colors = OrderedDict([('min. samples leaf', 'm'), ('max. features', 'b'), ('bootstrap', 'c'), ('criterion', 'g'), ('min. samples split', 'y'), ('strategy', 'r')])
elif type == 'rbf':
    results_file = '/home/vanrijn/experiments/archive/20170908/rbf/ranks.csv'
    colors = OrderedDict([('gamma', 'm'), ('complexity', 'b'), ('tolerance', 'g'), ('strategy', 'y'), ('shrinking', 'r')])
# elif type == 'poly':
#     results_file = '/home/vanrijn/experiments/archive/20170904/poly/ranks.csv'
#     colors = OrderedDict([('gamma', 'm'), ('coef0', 'mediumpurple'), ('complexity', 'c'), ('degree', 'green'), ('tolerance', 'limegreen'), ('imputation', 'y'), ('shrinking', 'r')])
elif type == 'sigmoid':
    results_file = '/home/vanrijn/experiments/archive/20170908/sigmoid/ranks.csv'
    colors = OrderedDict([('gamma', 'm'), ('complexity', 'b'),  ('coef0', 'c'), ('tolerance', 'g'), ('strategy', 'y'), ('shrinking', 'r')])
else:
    results_file = '/home/vanrijn/experiments/archive/20170908/adaboost/ranks.csv'
    colors = OrderedDict([('max. depth', 'm'),  ('learning rate', 'b'), ('algorithm', 'g'), ('iterations', 'y'), ('strategy', 'r')])

print(type, results_file)
print(colors)
x_vals = {}
y_vals = {}
area = {}
with open(results_file, 'r') as csvfile:
    reader = csv.DictReader(csvfile)
    count = 0

    for row in reader:
        count += 1
        # if count >= 10: break;

        task_id = row['task_id'][5:]
        del row['task_id']

        best_param = max(row, key=lambda k: float(row[k]))
        value = row[best_param]
        print(task_id, best_param, value)

        if best_param not in x_vals:
            x_vals[best_param] = []
            y_vals[best_param] = []
            area[best_param] = []

        task = openml.tasks.get_task(task_id)
        x_vals[best_param].append(float(task.get_dataset().qualities[x_axis_feature]))
        y_vals[best_param].append(float(task.get_dataset().qualities[y_axis_feature]))
        area[best_param].append(float(value) * 50)

# maintans a list of the params that were at least once most important
all_params = set(x_vals.keys())

undefined = all_params - colors.keys()
if len(undefined) > 0:
    raise ValueError('undefined parameters:', undefined)

plotted_items = []
legend_keys = []
for param, value in colors.items():
    if param in all_params:
        occurances = len(x_vals[param])
        current = plt.scatter(x_vals[param], y_vals[param], s=area[param], c=colors[param], alpha=0.9)
        plotted_items.append(current)
        legend_keys.append(param)
    else:
        # param was never most important
        pass

legend = plt.legend(plotted_items, legend_keys, scatterpoints=1, loc='upper right')
for idx in range(len(plotted_items)):
    legend.legendHandles[idx]._sizes = [50]

plt.xscale("log")
plt.yscale("log")
plt.axis((450,100000,3,2100))

plt.xlabel(x_axis_label, fontsize='xx-large')
plt.ylabel(y_axis_label, fontsize='xx-large')
plt.savefig('result_%s.pdf' %type, bbox_inches='tight')


text:
class CreateBuildings < ActiveRecord::Migration[5.0]
  def change
    create_table :buildings do |t|
      t.string :code
      t.string :name
      t.string :wing

      t.timestamps
    end
  end
end


text:
%Notes by Harsh Mistry
%Math 239
%based on Template from : https://www.cs.cmu.edu/~ggordon/10725-F12/template.tex

\documentclass{article}
\setlength{\oddsidemargin}{0.25 in}
\setlength{\evensidemargin}{-0.25 in}
\setlength{\topmargin}{-0.6 in}
\setlength{\textwidth}{6.5 in}
\setlength{\textheight}{8.5 in}
\setlength{\headsep}{0.75 in}
\setlength{\parindent}{0 in}
\setlength{\parskip}{0.1 in}
\usepackage{amsfonts,graphicx, amssymb}
\usepackage[fleqn]{amsmath}
\usepackage{fixltx2e}
\usepackage{color}
\usepackage{tcolorbox}
\usepackage{lipsum}
\usepackage{listings}
\usepackage{scrextend}
\tcbuselibrary{skins,breakable}
\usetikzlibrary{shadings,shadows}
\newcounter{lecnum}
\renewcommand{\thepage}{\thelecnum-\arabic{page}}
\renewcommand{\thesection}{\thelecnum.\arabic{section}}
\renewcommand{\theequation}{\thelecnum.\arabic{equation}}
\renewcommand{\thefigure}{\thelecnum.\arabic{figure}}
\renewcommand{\thetable}{\thelecnum.\arabic{table}}
\newcommand{\lecture}[4]{
   \pagestyle{myheadings}
   \thispagestyle{plain}
   \newpage
   \setcounter{lecnum}{#1}
   \setcounter{page}{1}

%Info Box
   \begin{center}
   \framebox{
      \vbox{\vspace{2mm}
    \hbox to 6.28in { {\bf Math 239 - Introduction to Combinatorics
	\hfill Spring 2017} }
       \vspace{4mm}
       \hbox to 6.28in { {\Large \hfill Lecture #1: #2  \hfill} }
       \vspace{2mm}
       \hbox to 6.28in { {\it Lecturer: #3 \hfill Notes By: #4} }
      \vspace{2mm}}
   }
   \end{center}

   \markboth{Lecture #1: #2}{Lecture #1: #2}

}

\renewcommand{\cite}[1]{[#1]}
\def\beginrefs{\begin{list}%
        {[\arabic{equation}]}{\usecounter{equation}
         \setlength{\leftmargin}{2.0truecm}\setlength{\labelsep}{0.4truecm}%
         \setlength{\labelwidth}{1.6truecm}}}
\def\endrefs{\end{list}}
\def\bibentry#1{\item[\hbox{[#1]}]}

\newcommand{\fig}[3]{
			\vspace{#2}
			\begin{center}
			Figure \thelecnum.#1:~#3
			\end{center}
	}

	\newcommand{\bs}{
		\texttt{\char`\\ \hspace{0.1cm}}
	}

\newcommand{\pipe}{\(\mid\)}
\newcommand{\ctr}{\(\wedge\)}

\newtheorem{theorem}{Theorem}[lecnum]
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{ex}[theorem]{Example}
\newtheorem{expx}[theorem]{Problem}
\newtheorem{prop}[theorem]{Proposition}
\newtheorem{claim}[theorem]{Claim}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{definition}[theorem]{Definition}
\newenvironment{proof}{{\bf Proof:}}{\hfill\rule{2mm}{2mm}}
\newcommand\E{\mathbb{E}}

%color definitions :
\definecolor{darkred}{rgb}{0.55, 0.0, 0.0}
\definecolor{lightcoral}{rgb}{0.94, 0.5, 0.5}
\definecolor{tomato}{rgb}{1.0, 0.39, 0.28}
\definecolor{lightgray}{rgb}{.9,.9,.9}
\definecolor{darkgray}{rgb}{.4,.4,.4}
\definecolor{purple}{rgb}{0.65, 0.12, 0.82}
\definecolor{lightgreen}{rgb}{0.56, 0.93, 0.56}
\definecolor{darkgreen}{rgb}{0.0, 0.2, 0.13}
\definecolor{limegreen}{rgb}{0.2, 0.8, 0.2}
\definecolor{lightblue}{rgb}{0.68, 0.85, 0.9}
\definecolor{darkblue}{rgb}{0.0, 0.0, 0.55}

%Environments
\newenvironment{exblock}[1]{%
    \tcolorbox[beamer,%
    noparskip,breakable,
    colback=lightgreen,colframe=darkgreen,%
    colbacklower=limegreen!75!lightgreen,%
    title=#1]}%
    {\endtcolorbox}

\newenvironment{ablock}[1]{%
    \tcolorbox[beamer,%
    noparskip,breakable,
    colback=lightcoral,colframe=darkred,%
    colbacklower=tomato!75!lightcoral,%
    title=#1]}%
    {\endtcolorbox}

\newenvironment{cblock}[1]{%
    \tcolorbox[beamer,%
    noparskip,breakable,
    colback=lightblue,colframe=darkblue,%
    colbacklower=darkblue!75!lightblue,%
    title=#1]}%
    {\endtcolorbox}

%Languages
\lstdefinelanguage{JavaScript}{
  keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break},
  keywordstyle=\color{blue}\bfseries,
  ndkeywords={class, export, boolean, throw, implements, import, this},
  ndkeywordstyle=\color{darkgray}\bfseries,
  identifierstyle=\color{black},
  sensitive=false,
  comment=[l]{//},
  morecomment=[s]{/*}{*/},
  commentstyle=\color{purple}\ttfamily,
  stringstyle=\color{red}\ttfamily,
  morestring=[b]',
  morestring=[b]"
}

%Listings
\lstset{
   language=JavaScript,
   backgroundcolor=\color{lightgray},
   extendedchars=true,
   basicstyle=\footnotesize\ttfamily,
   showstringspaces=false,
   showspaces=false,
   numbers=left,
   numberstyle=\footnotesize,
   numbersep=9pt,
   tabsize=2,
   breaklines=true,
   showtabs=false,
   captionpos=b
}

%Start
\begin{document}

\lecture{8}{May 17th, 2017}{Alan Arroyo Guevara}{Harsh Mistry}

\begin{ablock}{Remark}
The sum lemma generalizes when \(S_0, S_1, S_2, \ldots\) is a partition of S. $$\phi_S = \sum_{n \geq 0} \phi_{S_n}(x)$$
\end{ablock}

\section{Compositions of an Integer}
\begin{definition}
For integer \(n \geq 0, k \geq 0\), a \underline{composition} of n is a k-tuple of positive integers \(c_1, c_2, \ldots, c_k\) such that \(c_1 + c_2 + \ldots + c_k = n\)
\end{definition}

\begin{ablock}{Remark}
\begin{itemize}
\item The \(c_i\)'s are called the parts of the composition
\item There is one composition of 0, The empty composition
\end{itemize}
\end{ablock}

\subsection*{Tackling a Composition Problem}
\textbf{Notation :} \(\mathbb{N} = \langle 1, 2, 3, \ldots\rangle , \mathbb{N}_0 = \langle 0 , 1, 2, 3, \ldots \rangle\)

\textbf{Goal :} Craft a set S and weight function w, such that the number of compositions of n we are counting is \([x^n] \phi_S(x) \)

\textbf{Steps :}
\begin{enumerate}
\item Find a set S that fits your problem
\begin{itemize}
\item If your compositions have k parts, let S be a product of k sets.
\item w usually is the sum of the parts
\item If the number of parts is unrestricted then
\[S = S_0 \cup S_1 \cup S_2 \cup \ldots \]
each \(S_k\) is the number of compositions with k parts that we are considering.
\end{itemize}
\item Find \(\phi_S(x)\) by applying Sum and Product Lemmas
\item Find \([x^n] \phi_S(x)\), Using the tricks provided by the Inverse Bin. Series)
\end{enumerate}

\newpage
\begin{expx}
Let K, \(n \in \mathbb{N}, n \geq k\). \
How many compositions of n with k parts are there?\\
\newline
\textbf{Solution : }
\begin{enumerate}
\item \(S= \frac{\mathbb{N} \times \ldots \times \mathbb{N}}{k} = \mathbb{N}^k\) \\
For \((C_1, C_2, \ldots, C_k) \in S\), let w\((C_1, \ldots, C_k)\) = \(C_1 + C_2 + \ldots + C_k\)
\item By Product Lemma,
\[\begin{aligned}\phi_S(x) & = \phi_{\mathbb{N} \times \ldots \times \mathbb{N} }(x)\\
 & = \phi_{\mathbb{N}} (x) \cdot \phi_{\mathbb{N}} (x) \cdot \ldots \cdot \phi_{\mathbb{N}} (x) \\
 & = \left(\phi_{\mathbb{N}} (x)\right)^k \\
 & = (x^1 + x^2 + x^3 1 \ldots)^k \\
 & = (x(x^0 + x^1 + x^2 + \ldots))^k
 & = \left(\frac{x}{1-x}\right)^k \end{aligned}\]
 \item \[\begin{aligned}
 [x^n]\left(\frac{1}{1-x}\right)^k & = [x^n](x^k)(1-k)^{-k} \\
 & = [x^{n-k}](1-x)^{-k} \\
 & = [x^{n-k}] \sum_{j = 0} {{j + k - 1} \choose {k-1}} x^j \\
 & = {{n-k+k-1} \choose {k-1}} \\
 & = {{n - 1} \choose {k-1}}
 \end{aligned}\]
 \end{enumerate}
\end{expx}

\begin{expx} How many compositions of n are there? \\
\textbf{Solution : } Next lecture
\end{expx}

\end{document}


text:
.class Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle$2;
.super Ljava/lang/Object;
.source "OverlayDisplayAdapter.java"

# interfaces
.implements Ljava/lang/Runnable;

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$1:Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;

# direct methods
.method constructor <init>(Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;)V
    .locals 0

    .prologue
    .line 344
    iput-object p1, p0, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle$2;->this$1:Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public run()V
    .locals 4

    .prologue
    .line 348
    iget-object v1, p0, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle$2;->this$1:Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;

    iget-object v1, v1, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;->this$0:Lcom/android/server/display/OverlayDisplayAdapter;

    invoke-virtual {v1}, Lcom/android/server/display/OverlayDisplayAdapter;->getSyncRoot()Lcom/android/server/display/DisplayManagerService$SyncRoot;

    move-result-object v2

    monitor-enter v2

    .line 349
    :try_start_0
    iget-object v1, p0, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle$2;->this$1:Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;

    # getter for: Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;->mWindow:Lcom/android/server/display/OverlayDisplayWindow;
    invoke-static {v1}, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;->access$800(Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;)Lcom/android/server/display/OverlayDisplayWindow;

    move-result-object v0

    .line 350
    .local v0, "window":Lcom/android/server/display/OverlayDisplayWindow;
    iget-object v1, p0, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle$2;->this$1:Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;

    const/4 v3, 0x0

    # setter for: Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;->mWindow:Lcom/android/server/display/OverlayDisplayWindow;
    invoke-static {v1, v3}, Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;->access$802(Lcom/android/server/display/OverlayDisplayAdapter$OverlayDisplayHandle;Lcom/android/server/display/OverlayDisplayWindow;)Lcom/android/server/display/OverlayDisplayWindow;

    .line 351
    monitor-exit v2
    :try_end_0
    .catchall {:try_start_0 .. :try_end_0} :catchall_0

    .line 353
    if-eqz v0, :cond_0

    .line 354
    invoke-virtual {v0}, Lcom/android/server/display/OverlayDisplayWindow;->dismiss()V

    .line 356
    :cond_0
    return-void

    .line 351
    .end local v0    # "window":Lcom/android/server/display/OverlayDisplayWindow;
    :catchall_0
    move-exception v1

    :try_start_1
    monitor-exit v2
    :try_end_1
    .catchall {:try_start_1 .. :try_end_1} :catchall_0

    throw v1
.end method


text:
#include "FL.h"

#include "parameters.cpp"

int main(int argc, char **argv) {
    //size_t numberOfVisualWords = 500;
    size_t numberOfVisualWords = NUMBER_OF_VISUAL_WORDS;

    //Caminhos onde esta o arquivo txt gerado pelo o script python "selec_samples2.py"
    /*char const* const fileName_createDict = "/home/cibelle/Documentos/Databases/COIL100/train_paths.txt";
    char const* const fileName_createTrain = "/home/cibelle/Documentos/Databases/COIL100/train_paths.txt";
    char const* const fileName_createTest = "/home/cibelle/Documentos/Databases/COIL100/test_paths.txt";*/
    char const* const fileName_createDict = FILENAME_DICT;
    char const* const fileName_createTrain = FILENAME_TRAIN;
    char const* const fileName_createTest = FILENAME_TEST;
    char const* const fileName_superpixels = FILENAME_SUPERPIXEL;

    //cada posicao do vetor tem uma string para o caminho de uma imagem
    GVector* vectorSamplesUsed2CreateDict =  splitsLinesInTextFile(fileName_createDict);
    GVector* vectorSamplesUsed2TrainClassifier =  splitsLinesInTextFile(fileName_createTrain);
    GVector* vectorSamplesUsed2TestClassifier =  splitsLinesInTextFile(fileName_createTest);
    GVector* vectorSamplesUsed2Superpixel =  splitsLinesInTextFile(fileName_superpixels);

    //apenas checkando se o vetor vazio. Caso o vetor esteja vazio, talvez seu caminho ate o arquivo
    //txt nao esteja correto
    if(vectorSamplesUsed2CreateDict->size == 0){
        printf("no path found");
        return -1;
    }

    if(vectorSamplesUsed2TrainClassifier->size == 0){
        printf("no path found");
        return -1;
    }

    if(vectorSamplesUsed2TestClassifier->size == 0){
        printf("no path found");
        return -1;
    }

    printf("Escolha descritor:\n");
    printf("\t1: Histograma de cor\n");
    printf("\t2: HOG\n");
    printf("\t3: Histograma de cor + HOG\n");
    int option;
    do {
        scanf("%d", &option);
    } while(option < 1 && option > 3);

    //pipeline para a construncao do dicionario. Para mais detalhes olhe a imagem que esta
    //em data/bowArquiteturaImplementada.png

    //a estrutura bow manager e encarregada de fazer o processo do bow
    BagOfVisualWordsManager* bowManager = createBagOfVisualWordsManager();

    ////////////////////////////////////////////////////////////////////////
    //Passando os vetores que contem os caminhos das imagens para...
    bowManager->pathsToImages_dictionery = vectorSamplesUsed2CreateDict;//criar o dicionario
    bowManager->pathsToImages_train = vectorSamplesUsed2TrainClassifier;//treinar o classificador
    bowManager->pathsToImages_test = vectorSamplesUsed2TestClassifier;//testar o classificador
    bowManager->pathsToImages_isf = vectorSamplesUsed2Superpixel;
    //////////////////////////////////////////////////////////////////////

    printf("Escolha método grid:\n");
    printf("\t1: Grid simples\n");
    printf("\t2: Grid superpixel com gradiente\n");
    printf("\t3: Grid superpixel com histograma de cor\n");
    int optionGrid;
    do {
        scanf("%d", &optionGrid);
    } while(optionGrid < 1 && optionGrid > 3);

    if(optionGrid == 1) {

        //////////////////////////////////////////////////////////////////////
        //metodo de sampling que vai ser usado para criar os patchs. Se vc passar NULL aqui o estrutura
        // do bow vai criar um vetor de tamanho 1 onde o unico elemento desse vetor vai ser a imagem.
        bowManager->imageSamplerFunction = gridSamplingBow;//ponteiro da funcao para o sampling

        //Nesta demo o metodo de sampling  usado é o grid. Entao eu vou criar um argument list
        //para colocar os parametros do metodo de grinding que eu fiz.
        //Note que o cabecalho geral para a funcao de sammpling e
        //GVector* minhaFuncaoDeSampling(Image* image, BagOfVisualWordsManager* bagOfVisualWordsManager);
        ArgumentList* gridSamplingArguments = createArgumentList();
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_X); //patch size X
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_Y); //patch size Y
        bowManager->argumentListOfSampler = gridSamplingArguments;//passando a lista de argumentos para o bow manager
        //////////////////////////////////////////////////////////
    } else if(optionGrid == 2) {
        bowManager->imageSamplerFunction = samplingByISFBow;//ponteiro da funcao para o sampling
        ArgumentList* gridSamplingArguments = createArgumentList();
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,GRID_GRADIENT_THRESOULD); //patch size X
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_Y); //patch size Y
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_X); //patch size X
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,GRID_WIDTH_ADJ_REL); //patch size Y
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,GRID_HEIGHT_ADJ_REL); //patch size X
        bowManager->argumentListOfSampler = gridSamplingArguments;//passando a lista de argumentos para o bow manager
    } else if(optionGrid == 3) {
        bowManager->imageSamplerFunction = samplingByISFColorBow;//ponteiro da funcao para o sampling
        ArgumentList* gridSamplingArguments = createArgumentList();
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_Y); //patch size Y
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,PATCH_SIZE_X); //patch size X
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,DIFF_SUPER_PIXELS); //patch size Y
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,BIN_SIZE); //patch size X
        ARGLIST_PUSH_BACK_AS(size_t,gridSamplingArguments,SPARSE_HIST); //patch size X
        bowManager->argumentListOfSampler = gridSamplingArguments;//passando a lista de argumentos para o bow manager
    }

    /////////////////////////////////////////////////////////////////////////////
    //Essa função serve como um garbage collector para o metodo do sampling. Ao final de
    //cada iteracao, ela limpa da memoria os patchs gerados.
    //Se por acaso seu metodo de sampling nao gerar um vetor de imagens (GVector* de Image*),
    //voce pode passar NULL, porém fique consciente que vai ter um pouco de memory leak.
    //Ao final do programa seu sistema operional vai limpar toda a sujeira.
    bowManager->freeFunction2SamplerOutput = destroyImageVoidPointer;
    //bowManager->freeFunction2SamplerOutput = NULL;
    /////////////////////////////////////////////////

    ///////////////////////////////////////
    if(option == 1) { // histograma de cor

        bowManager->featureExtractorFunction = computeColorHistogramBow;//ponteiro da funcao para a extracao de features
        ArgumentList* colorFeatureExtractorArguments = createArgumentList();
        size_t nbins = COLOR_HISTOGRAM_NBINS;
        ARGLIST_PUSH_BACK_AS(size_t,colorFeatureExtractorArguments,nbins); //nBins per channel
        ARGLIST_PUSH_BACK_AS(size_t,colorFeatureExtractorArguments,nbins*nbins*nbins); //total number of channels
        bowManager->argumentListOfFeatureExtractor = colorFeatureExtractorArguments; //passando a lista de argumentos do feature extractor para o bow manager

    } else if(option == 2) { // hog

        bowManager->featureExtractorFunction = computeHogBow;
        ArgumentList* hogFeatureExtractorArguments = createArgumentList();
        ARGLIST_PUSH_BACK_AS(size_t,hogFeatureExtractorArguments,HOG_BLOCKS_X); //número de blocos na horizontal
        ARGLIST_PUSH_BACK_AS(size_t,hogFeatureExtractorArguments,HOG_BLOCKS_Y); //número de blocos na vertical
        ARGLIST_PUSH_BACK_AS(size_t,hogFeatureExtractorArguments,HOG_THETA); //theta
        bowManager->argumentListOfFeatureExtractor = hogFeatureExtractorArguments; //passando a lista de argumentos do feature extractor para o bow manager

    } else { // histograma de cor + hog
        bowManager->featureExtractorFunction = computeColorAndHogBow;
        ArgumentList* colorAndhogFeatureExtractorArguments = createArgumentList();
        ARGLIST_PUSH_BACK_AS(size_t,colorAndhogFeatureExtractorArguments,HOG_BLOCKS_X); //número de blocos na horizontal
        ARGLIST_PUSH_BACK_AS(size_t,colorAndhogFeatureExtractorArguments,HOG_BLOCKS_Y); //número de blocos na vertical
        ARGLIST_PUSH_BACK_AS(size_t,colorAndhogFeatureExtractorArguments,HOG_THETA); //theta
        size_t nbins = COLOR_HISTOGRAM_NBINS;
        ARGLIST_PUSH_BACK_AS(size_t,colorAndhogFeatureExtractorArguments,nbins); //nBins per channel
        ARGLIST_PUSH_BACK_AS(size_t,colorAndhogFeatureExtractorArguments,nbins*nbins*nbins); //total number of channels
        bowManager->argumentListOfFeatureExtractor = colorAndhogFeatureExtractorArguments; //passando a lista de argumentos do feature extractor para o bow manager

    }

    ///////////////////////////////////////////////////////
    //Existem muitas maneiras de computar distancias entre pontos e vetores. A mais comum delas talvez
    //seja a distancia Euclidianda (norma l2). Neste exemplo eu vou usar a norma l1.
    //Quando vc implementar seu metodo de sampling, feature extraxtion, ou clustering, voce
    //pode usar essa funcao distancia.
    bowManager->distanceFunction = computeNormalizedL1Norm;
    bowManager->argumentListOfDistanceFunction = NULL;
    ////////////////////////////////////////////////////

    /////////////////////////////////////////////////////
    //Aqui precisamos definir qual funcao de clsutering vamos usar para encontrar as palavras
    //do dicionario. Eu optei de usar o kmeans clustering. Meu metodo do kmeans recebe 6 parametros,
    //desta forma eu preciso criar uma ArgumentList com 6 parametros.
    //Note que o cabecalho geral para a funcao de clustering e
    //typedef Matrix* minhaFuncaoDeClustering(Matrix* outputFeatureExtractor_allSamples, BagOfVisualWordsManager* bagOfVisualWordsManager);
    bowManager->clusteringFunction = kmeansClusteringBow;
    ArgumentList* clusteringMethodArguments = createArgumentList();
    ARGLIST_PUSH_BACK_AS(size_t,clusteringMethodArguments,numberOfVisualWords); //number of words
    ARGLIST_PUSH_BACK_AS(size_t,clusteringMethodArguments,100); //maximum number of iterations
    ARGLIST_PUSH_BACK_AS(double,clusteringMethodArguments,0.0001); //tolerance
    ARGLIST_PUSH_BACK_AS(int,clusteringMethodArguments,0); //seed
    ARGLIST_PUSH_BACK_AS(DistanceFunction,clusteringMethodArguments,computeNormalizedL1Norm); //distance function
    ARGLIST_PUSH_BACK_AS(ArgumentList*,clusteringMethodArguments,NULL); //
    bowManager->argumentListOfClustering = clusteringMethodArguments;
    ///////////////////////////////////////////////////////////////

    ////////////
    //computa o dicionario
    computeDictionery(bowManager);
    /////////////

    //////////////////////
    //define a funcao para montar o histograma
    bowManager->mountHistogramFunction = computeCountHistogram_bow;
    bowManager->argumentListOfHistogramMounter = NULL;
    ///////////////////////

    /////////////////////////////////////////////////
    //criar um classificador e define os parametros
    //do classficiador. Em seguida, o bow manager recebe
    //o ponteiro do classificador. Desta forma o classificador
    //podera ser usado internamente dentro do bow manager.

    //SVM Classifier
    SVM_Classifier* classifiersvm = createSVMClassifier();
    classifiersvm->param.kernel_type = RBF;
    classifiersvm->param.gamma = 3.5;
    bowManager->classifier = (void*)classifiersvm;
    bowManager->fitFunction = svm_Classifier_fit;
    bowManager->storeTrainData = false;
    bowManager->predictFunction = svm_Classifier_predict;
    bowManager->storePredictedData = false;
    bowManager->freeFunctionClassifier = destroySVMClassifierForVoidPointer;
    //////////////////////////////////////

    ///////
    //monta os histogramas, le os label e em seguida treina o classificador
    trainClassifier(bowManager);
    //////////

    /////////////////////////////////////////////////////
    //monta os histogramas e usa o classificador treinado para
    //classificar as amostras do conjunto de teste
    GVector* labelsPredicted = predictLabels(bowManager);
    //////////////////////////

    //////////////////////////
    //Le os true labels das imagens e checa com os labels predizidos pelo o classificador.
    //computa uma simples acuracia (numero de amostras rotuladas corretamente / numero de amostras do conjunto)

    GVector* trueLabels = createNullVector(bowManager->pathsToImages_test->size,sizeof(int));

    int hit = 0;
    printf("file | predicted true\t\tcorrect\n");
    char symbol;
    for (size_t index = 0; index < bowManager->pathsToImages_test->size; ++index) {
        symbol = 'X';
        char * path = VECTOR_GET_ELEMENT_AS(char*,bowManager->pathsToImages_test,index);
        VECTOR_GET_ELEMENT_AS(int,trueLabels,index) = findTrueLabelInName(path);
        int trueLabel = VECTOR_GET_ELEMENT_AS(int,trueLabels,index);
        int predictedLabel = VECTOR_GET_ELEMENT_AS(int,labelsPredicted,index);
        if(trueLabel == predictedLabel){
            hit++;
            symbol = 'O';

        }
        printf("%s | %03d %03d\t\t%c\n",
               path,
               VECTOR_GET_ELEMENT_AS(int,labelsPredicted,index),
               VECTOR_GET_ELEMENT_AS(int,trueLabels,index),symbol
        );
    }

    printf("Acucaria:%f\n", ((double)hit)/bowManager->pathsToImages_test->size);
    /////////////////////////////////////
    destroyBagOfVisualWordsManager(&bowManager);
    destroyVector(&trueLabels);
    destroyVector(&labelsPredicted);

    return 0;

}


text:
require File.expand_path('../test_helper', __FILE__)

class ConditionTest < UnitTest

  def noindex(app)
    condition = lambda { |env| env['SERVER_NAME'] != 'www.exemple.io' }
    Rack::Lint.new(Rack::Noindex.new(app, condition))
  end

  def test_custom
    request = Rack::MockRequest.env_for("/", {'SERVER_NAME' => 'www.exemple.io'})
    response = noindex(app).call(request)
    assert_equal nil, response[1]["X-Robots-Tag"]
  end

  def test_custom_no_index
    request = Rack::MockRequest.env_for("/")
    response = noindex(app).call(request)
    assert_equal 'noindex', response[1]["X-Robots-Tag"]
  end

end


text:
<?php
class Kwc_Blog_Directory_Generator extends Kwf_Component_Generator_Page_Table
{
    protected function _formatSelect($parentData, $select)
    {
        $ret = parent::_formatSelect($parentData, $select);
        if (!$ret) return $ret;

        if (!$select || !$select->getPart(Kwf_Component_Select::IGNORE_VISIBLE)) {
            $ret->where('publish_date <= NOW()');
        }

        $ret->order('publish_date', 'DESC');
        return $ret;
    }
}


text:
ape
===

API docs? Nope, ape docs!

ape generates API documentation in github-flavored-markup from comments in your code, and places them in line with the actual code. This allows for very easy integration with github.
Optionally, ape can also output to html with a built-in jade template, or one you specify.

See lib/template.jade for an example template, lib/ape.html and lib/ape.md are example output.

To install:

    sudo npm install -g ape

And how to use:

    Usage: node ./bin/ape [input file|directory list]

    Options:
      --md            Output as markdown        [boolean]  [default: true]
      --html          Output as HTML            [boolean]  [default: false]
      --template, -t  Template for HTML output  [string]
      --output, -o    Output directory          [string]

Currently python, javascript, ruby, lua, coffeescript, C, C++, Perl, PHP, C#, ObjC, SQL, Bash, CSS, and ActionScript are supported. Feel free to submit a pull request for additional languages!


text: Node.js discord bot


text:
import React from 'react';
import ReactDOM from 'react-dom';
import {Link} from 'react-router-dom';
import Search from './search';
import SignIn from './signin';
import SignUp from './signup';
import Create from './create';
var axios = require('axios');

class Navbar extends React.Component {
	constructor(props){
		super(props)
		this.state = {
			// events: [],
			// currentEvent: events[0]
		}
		this.handleSignOut = this.handleSignOut.bind(this);
	}

	handleSignOut(){
		axios.get('/logout')
		.then((data) => {
			console.log(data);
		})
		.catch(error => {
			console.log(error);
		})
		console.log('clicked')
		window.isAuth = false;
	}

	render(){
		return (

				<Link to="/" style={{textDecoration: 'none' }} className="nav-brand" id="title">Greenfield</Link>

				<Link to="/signup" style={{textDecoration: 'none' }} className="Link nav-link h4">Sign Up</Link>

				<Link to="/signin" style={{textDecoration: 'none' }} className="Link nav-link h4">Sign In</Link>

				<Link to="/create" style={{textDecoration: 'none' }} className="Link nav-link h4">Create</Link>

				<Link to="/signin" style={{textDecoration: 'none' }} className="Link nav-link h4" id="logout" onClick={this.handleSignOut} >Sign Out</Link>

		)
	}
}

export default Navbar;


text:
import { Pipeline, Document } from 'ml-admin';
import { MLProduct } from '../models/product';
export declare class PIMPipeline implements Pipeline<any, MLProduct> {
    transform(input: Document<any>): Document<MLProduct>[];
}


text:
<!DOCTYPE html>

	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width">
	<title>SparkMonitor JavaScript Documentation Module: currentcell</title>

	<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">

	<link type="text/css" rel="stylesheet" href="styles/site.lumen.css">

		SparkMonitor JavaScript Documentation
		<button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#topNavigation">

        </button>

				Modules

CellMonitor

SparkMonitor

TaskChart

Timeline

currentcell

module

taskdetails

				Classes

SparkMonitor~SparkMonitor

CellMonitor~CellMonitor

TaskChart~TaskChart

Timeline~Timeline

                <form class="navbar-form" role="search">

                        <input type="text" class="form-control" placeholder="Search" name="q" id="search-input">

                            <button class="btn btn-default" id="search-submit"></button>

                </form>

Module: currentcell

Module to detect the currently running cell.

The notebook sends execution requests, and they queue up on the message channel.
There is no straight forward way to detect the currently running cell.
Here we use a queue to store execution requests and dequeue elements as the kernel becomes idle after the requests

Members

<inner> cell_queue

        The list of cells queued for execution.

Methods

<inner> cell_execute_called()

        Called when an execute.CodeCell event occurs. This means an execute request was sent for the current cell.

<inner> cell_execute_finished()

        Called when the kernel becomes idle. This means that a cell finished executing.

<inner> getRunningCell()

Returns:

    - The running cell, or null.

        Type

CodeCell

<inner> getLastCell()

Returns:

    - The last run cell, or null.

        Type

CodeCell

<inner> cell_deleted(event, data)

        Called when a cell is deleted

Parameters:

        Name

        Type

        Description

                event

event

            The event object,

                data

data

            data of the event, contains the cell

<inner> register()

        Register event listeners for detecting running cells.

            <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>

Search results

            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

	Documentation generated by JSDoc 3.5.4

		on 2017-08-27T18:34:47+05:30

	using the DocStrap template.


text:
TIME_CONVERSION_SOURCES = convertionAlgorithms.c

SOURCES += $(TIME_CONVERSION_SOURCES:%.c=time/conversion/%.c)
SOURCES += $(wildcard time/conversion/*_config.c)
SEC_SOURCES += $(wildcard time/conversion/*.sec)

include time/conversion/tests/Makefile


text:
<!DOCTYPE html>

    <meta charset="UTF-8" />
    <meta name="robots" content="index, follow, all" />
    <title>Valit\Contracts\Logic | Valit API</title>

            <link rel="stylesheet" type="text/css" href="../../css/bootstrap.min.css">
        <link rel="stylesheet" type="text/css" href="../../css/bootstrap-theme.min.css">
        <link rel="stylesheet" type="text/css" href="../../css/sami.css">

        <meta name="MobileOptimized" content="width">
        <meta name="HandheldFriendly" content="true">
        <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">

                    <form action="#" method="GET">
                <select id="version-switcher" name="version">
                                            <option value="../../../2.0.0-alpha/index.html" data-version="2.0.0-alpha">2.0.0-alpha</option>
                                            <option value="../../../2.0.0/index.html" data-version="2.0.0">2.0.0</option>
                                            <option value="../../../2.0.1/index.html" data-version="2.0.1">2.0.1</option>
                                            <option value="../../../1.0.0/index.html" data-version="1.0.0">1.0.0</option>
                                            <option value="../../../1.0.1/index.html" data-version="1.0.1">1.0.1</option>
                                            <option value="../../../1.0.2/index.html" data-version="1.0.2">1.0.2</option>
                                            <option value="../../../0.8.0/index.html" data-version="0.8.0">0.8.0</option>
                                            <option value="../../../0.8.1/index.html" data-version="0.8.1">0.8.1</option>
                                            <option value="../../../master/index.html" data-version="master">master dev branch</option>
                                    </select>
            </form>

        <form id="search-form" action="../../search.html" method="GET">

            <input name="search"
                   class="typeahead form-control"
                   type="search"
                   placeholder="Search">
        </form>

                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-elements">
                    Toggle navigation

                </button>
                Valit API

Classes

Namespaces

Interfaces

Traits

Index

Search

interface

Valit

\

Contracts

\

Logic

            Logic

    interface
    Logic        (View source)

Methods

                    AssertionResult

                    execute(bool $hasValue = false, mixed $value = null)

Execute the logic.

                    AssertionResult

                    withValue(mixed $value)

Execute the logic with a given value.

                    AssertionResult

                    withoutValue()

Execute the logic without a value.

                    string

                    requires()

The requirements of this logic.

Details

at         line 17

                            AssertionResult
    execute(bool $hasValue = false, mixed $value = null)

Execute the logic.

Parameters

                bool
                $hasValue

                mixed
                $value

Return Value

            AssertionResult

at         line 26

                            AssertionResult
    withValue(mixed $value)

Execute the logic with a given value.

Parameters

                mixed
                $value

Return Value

            AssertionResult

at         line 33

                            AssertionResult
    withoutValue()

Execute the logic without a value.

Return Value

            AssertionResult

at         line 42

                            string
    requires()

The requirements of this logic.

It can be 'none', 'simple value' or 'container'

Return Value

            string

        Generated by Sami, the API Documentation Generator.


text:
package org.tinymediamanager.ui.tvshows.dialogs;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.AbstractAction;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SpinnerDateModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;

import org.apache.commons.lang3.StringUtils;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.observablecollections.ObservableCollections;
import org.jdesktop.swingbinding.JComboBoxBinding;
import org.jdesktop.swingbinding.JListBinding;
import org.jdesktop.swingbinding.JTableBinding;
import org.jdesktop.swingbinding.SwingBindings;
import org.tinymediamanager.Globals;
import org.tinymediamanager.core.Constants;
import org.tinymediamanager.core.MediaFileType;
import org.tinymediamanager.core.entities.MediaFile;
import org.tinymediamanager.core.threading.TmmTask;
import org.tinymediamanager.core.threading.TmmTaskManager;
import org.tinymediamanager.core.tvshow.TvShowList;
import org.tinymediamanager.core.tvshow.entities.TvShow;
import org.tinymediamanager.core.tvshow.entities.TvShowActor;
import org.tinymediamanager.core.tvshow.entities.TvShowEpisode;
import org.tinymediamanager.scraper.Certification;
import org.tinymediamanager.scraper.MediaGenres;
import org.tinymediamanager.scraper.MediaType;
import org.tinymediamanager.scraper.trakttv.SyncTraktTvTask;
import org.tinymediamanager.ui.EqualsLayout;
import org.tinymediamanager.ui.IconManager;
import org.tinymediamanager.ui.MainWindow;
import org.tinymediamanager.ui.TableColumnResizer;
import org.tinymediamanager.ui.TableSpinnerEditor;
import org.tinymediamanager.ui.TmmFontHelper;
import org.tinymediamanager.ui.UTF8Control;
import org.tinymediamanager.ui.components.AutocompleteComboBox;
import org.tinymediamanager.ui.components.ImageLabel;
import org.tinymediamanager.ui.dialogs.ImageChooserDialog;
import org.tinymediamanager.ui.dialogs.ImageChooserDialog.ImageType;
import org.tinymediamanager.ui.dialogs.TmmDialog;

import com.jgoodies.forms.factories.FormFactory;
import com.jgoodies.forms.layout.ColumnSpec;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.forms.layout.RowSpec;

/**
 * The Class TvShowEditor.
 *
 * @author Manuel Laggner
 */
public class TvShowEditorDialog extends TmmDialog {
  private static final long           serialVersionUID = 3270218410302989845L;
  /**
   * @wbp.nls.resourceBundle messages
   */
  private final static ResourceBundle BUNDLE           = ResourceBundle.getBundle("messages", new UTF8Control()); //$NON-NLS-1$
  private static final Date           INITIAL_DATE     = new Date(0);

  private TvShow                             tvShowToEdit;
  private TvShowList                         tvShowList    = TvShowList.getInstance();
  private List<TvShowActor>                  actors        = ObservableCollections.observableList(new ArrayList<TvShowActor>());
  private List<MediaGenres>                  genres        = ObservableCollections.observableList(new ArrayList<MediaGenres>());
  // private List<MediaTrailer> trailers = ObservableCollections
  // .observableList(new ArrayList<MediaTrailer>());
  private List<String>                       tags          = ObservableCollections.observableList(new ArrayList<String>());
  private List<TvShowEpisodeEditorContainer> episodes      = ObservableCollections.observableList(new ArrayList<TvShowEpisodeEditorContainer>());
  private boolean                            continueQueue = true;

  /**
   * UI elements
   */
  private final JPanel details1Panel = new JPanel();
  private final JPanel details2Panel = new JPanel();
  private final JPanel episodesPanel = new JPanel();
  private JTextField   tfTitle;
  private JSpinner     spYear;
  private JTextPane    tpPlot;
  private JTable       tableActors;
  private JLabel       lvlTvShowPath;
  private ImageLabel   lblPoster;
  private ImageLabel   lblFanart;
  private ImageLabel   lblBanner;
  private JSpinner     spRuntime;
  private JTextField   tfStudio;
  private JList        listGenres;
  private JComboBox    cbGenres;
  private JSpinner     spRating;
  private JComboBox    cbCertification;
  private JComboBox    cbStatus;
  private JTextField   tfImdbId;
  private JTextField   tfTvdbId;
  private JLabel       lblImdbId;
  private JLabel       lblTvdbId;
  // private JTable tableTrailer;
  private JComboBox    cbTags;
  private JList        listTags;
  private JSpinner     spDateAdded;
  private JSpinner     spPremiered;
  private JTable       tableEpisodes;
  private JTextField   tfSorttitle;
  private ImageLabel   lblLogo;
  private ImageLabel   lblClearart;
  private ImageLabel   lblThumb;

  private JTableBinding<TvShowActor, List<TvShowActor>, JTable>                                   jTableBinding;
  private JListBinding<MediaGenres, List<MediaGenres>, JList>                                     jListBinding;
  // private JTableBinding<MediaTrailer, List<MediaTrailer>, JTable> jTableBinding_1;
  private JComboBoxBinding<String, TvShowList, JComboBox>                                         jComboBinding;
  private JListBinding<String, List<String>, JList>                                               jListBinding_1;
  private JTableBinding<TvShowEpisodeEditorContainer, List<TvShowEpisodeEditorContainer>, JTable> jTableBinding_2;

  /**
   * Instantiates a new tv show editor dialog.
   *
   * @param tvShow
   *          the tv show
   * @param inQueue
   *          the in queue
   */
  public TvShowEditorDialog(TvShow tvShow, boolean inQueue) {
    super(BUNDLE.getString("tvshow.edit"), "tvShowEditor"); //$NON-NLS-1$
    setBounds(5, 5, 950, 700);

    tvShowToEdit = tvShow;
    getContentPane().setLayout(new BorderLayout());
    {
      JPanel panelPath = new JPanel();
      getContentPane().add(panelPath, BorderLayout.NORTH);
      panelPath.setLayout(new FormLayout(
          new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.DEFAULT_COLSPEC,
              FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, },
          new RowSpec[] { FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("15px"), FormFactory.RELATED_GAP_ROWSPEC, }));

      JLabel lblTvShowPathT = new JLabel(BUNDLE.getString("metatag.path")); //$NON-NLS-1$
      panelPath.add(lblTvShowPathT, "2, 2, left, top");

      lvlTvShowPath = new JLabel("");
      TmmFontHelper.changeFont(lblTvShowPathT, 1.166, Font.BOLD);
      panelPath.add(lvlTvShowPath, "5, 2, left, top");
    }

    JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.NORTH);
    tabbedPane.addTab(BUNDLE.getString("metatag.details"), details1Panel); //$NON-NLS-1$
    getContentPane().add(tabbedPane, BorderLayout.CENTER);

    details1Panel.setBorder(new EmptyBorder(5, 5, 5, 5));
    details1Panel.setLayout(new FormLayout(
        new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("max(40dlu;default)"), FormFactory.RELATED_GAP_COLSPEC,
            ColumnSpec.decode("50px:grow"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("50px"), FormFactory.RELATED_GAP_COLSPEC,
            ColumnSpec.decode("100px:grow"), FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("50px:grow"), FormFactory.UNRELATED_GAP_COLSPEC,
            FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("250px:grow"), FormFactory.RELATED_GAP_COLSPEC, },
        new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("top:max(75px;default)"),
            FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("75px:grow"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.NARROW_LINE_GAP_ROWSPEC, RowSpec.decode("default:grow"), FormFactory.RELATED_GAP_ROWSPEC,
            RowSpec.decode("fill:30px:grow(2)"), }));

    {
      JLabel lblTitle = new JLabel(BUNDLE.getString("metatag.title")); //$NON-NLS-1$
      details1Panel.add(lblTitle, "2, 2, right, default");
    }
    {
      tfTitle = new JTextField();
      details1Panel.add(tfTitle, "4, 2, 7, 1, fill, default");
      tfTitle.setColumns(10);
    }
    {
      lblPoster = new ImageLabel();
      lblPoster.setAlternativeText(BUNDLE.getString("image.notfound.poster")); //$NON-NLS-1$
      lblPoster.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
          ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.POSTER, tvShowList.getArtworkProviders(), lblPoster,
              null, null, MediaType.TV_SHOW);
          dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
          dialog.setVisible(true);
        }
      });
      lblPoster.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
      details1Panel.add(lblPoster, "12, 2, 3, 17, fill, fill");
    }
    {
      JLabel lblSortTitle = new JLabel(BUNDLE.getString("metatag.sorttitle")); //$NON-NLS-1$
      details1Panel.add(lblSortTitle, "2, 4, right, default");
    }
    {
      tfSorttitle = new JTextField();
      details1Panel.add(tfSorttitle, "4, 4, 7, 1, fill, default");
      tfSorttitle.setColumns(10);
    }
    {
      JLabel lblYear = new JLabel(BUNDLE.getString("metatag.year")); //$NON-NLS-1$
      details1Panel.add(lblYear, "2, 6, right, default");
    }
    {
      spYear = new JSpinner();
      details1Panel.add(spYear, "4, 6, fill, top");
    }
    {
      JLabel lblpremiered = new JLabel(BUNDLE.getString("metatag.premiered")); //$NON-NLS-1$
      details1Panel.add(lblpremiered, "8, 6, right, default");
    }
    {
      spPremiered = new JSpinner(new SpinnerDateModel());
      details1Panel.add(spPremiered, "10, 6");
    }
    {
      JLabel lblRuntime = new JLabel(BUNDLE.getString("metatag.runtime")); //$NON-NLS-1$
      details1Panel.add(lblRuntime, "2, 8, right, default");
    }
    {
      spRuntime = new JSpinner();
      details1Panel.add(spRuntime, "4, 8, fill, default");
    }

    {
      JLabel lblMin = new JLabel(BUNDLE.getString("metatag.minutes")); //$NON-NLS-1$
      details1Panel.add(lblMin, "6, 8");
    }
    {
      JLabel lblRating = new JLabel(BUNDLE.getString("metatag.rating")); //$NON-NLS-1$
      details1Panel.add(lblRating, "2, 10, right, default");
    }
    {
      spRating = new JSpinner();
      details1Panel.add(spRating, "4, 10");
    }
    {
      JLabel lblCertification = new JLabel(BUNDLE.getString("metatag.certification")); //$NON-NLS-1$
      details1Panel.add(lblCertification, "8, 10, right, default");
    }
    {
      cbCertification = new JComboBox();
      for (Certification cert : Certification.getCertificationsforCountry(Globals.settings.getTvShowSettings().getCertificationCountry())) {
        cbCertification.addItem(cert);
      }
      details1Panel.add(cbCertification, "10, 10, fill, default");
    }
    {
      lblImdbId = new JLabel(BUNDLE.getString("metatag.imdb")); //$NON-NLS-1$
      details1Panel.add(lblImdbId, "2, 12, right, default");
    }
    {
      tfImdbId = new JTextField();
      lblImdbId.setLabelFor(tfImdbId);
      details1Panel.add(tfImdbId, "4, 12, fill, default");
      tfImdbId.setColumns(10);
    }
    {
      lblTvdbId = new JLabel(BUNDLE.getString("metatag.tvdb")); //$NON-NLS-1$
      details1Panel.add(lblTvdbId, "8, 12, right, default");
    }
    {
      tfTvdbId = new JTextField();
      lblTvdbId.setLabelFor(tfTvdbId);
      details1Panel.add(tfTvdbId, "10, 12, fill, default");
      tfTvdbId.setColumns(10);
    }
    {
      JLabel lblStatus = new JLabel(BUNDLE.getString("metatag.status")); //$NON-NLS-1$
      details1Panel.add(lblStatus, "2, 14, right, default");
    }
    {
      cbStatus = new JComboBox(new String[] { "", "Continuing", "Ended" });
      details1Panel.add(cbStatus, "4, 14, fill, default");
    }
    {
      JLabel lblDateAdded = new JLabel(BUNDLE.getString("metatag.dateadded")); //$NON-NLS-1$
      details1Panel.add(lblDateAdded, "8, 14, right, default");
    }
    {
      spDateAdded = new JSpinner(new SpinnerDateModel());
      details1Panel.add(spDateAdded, "10, 14");
    }
    spDateAdded.setValue(tvShow.getDateAdded());
    {
      JLabel lblPlot = new JLabel(BUNDLE.getString("metatag.plot")); //$NON-NLS-1$
      details1Panel.add(lblPlot, "2, 16, right, top");
    }
    {
      JScrollPane scrollPanePlot = new JScrollPane();
      details1Panel.add(scrollPanePlot, "4, 16, 7, 3, fill, fill");
      {
        tpPlot = new JTextPane();
        scrollPanePlot.setViewportView(tpPlot);
      }
    }
    {
      JLabel lblStudio = new JLabel(BUNDLE.getString("metatag.studio")); //$NON-NLS-1$
      details1Panel.add(lblStudio, "2, 20, right, top");
    }
    {
      tfStudio = new JTextField();
      details1Panel.add(tfStudio, "4, 20, 7, 1");
    }

    /**
     * DetailsPanel 2
     */
    tabbedPane.addTab(BUNDLE.getString("metatag.details2"), details2Panel); //$NON-NLS-1$
    details2Panel.setBorder(new EmptyBorder(5, 5, 5, 5));
    details2Panel.setLayout(new FormLayout(
        new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("max(40dlu;default)"), FormFactory.RELATED_GAP_COLSPEC,
            ColumnSpec.decode("100px:grow(2)"), FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC,
            ColumnSpec.decode("100px:grow"), FormFactory.RELATED_GAP_COLSPEC, },
        new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("fill:30px:grow"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("default:grow"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC,
            FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("default:grow(2)"), }));
    {
      JLabel lblActors = new JLabel(BUNDLE.getString("metatag.actors")); //$NON-NLS-1$
      details2Panel.add(lblActors, "2, 2, right, default");
    }
    {
      JScrollPane scrollPane = new JScrollPane();
      details2Panel.add(scrollPane, "4, 2, 1, 7");
      {
        tableActors = new JTable();
        scrollPane.setViewportView(tableActors);
      }
    }
    {
      JLabel lblGenres = new JLabel(BUNDLE.getString("metatag.genre")); //$NON-NLS-1$
      details2Panel.add(lblGenres, "6, 2");
    }
    {
      JButton btnAddActor = new JButton("Add Actor");
      btnAddActor.setMargin(new Insets(2, 2, 2, 2));
      btnAddActor.setAction(new AddActorAction());
      btnAddActor.setIcon(IconManager.LIST_ADD);
      details2Panel.add(btnAddActor, "2, 4, right, top");
    }
    {
      JScrollPane scrollPaneGenres = new JScrollPane();
      details2Panel.add(scrollPaneGenres, "8, 2, 1, 5");
      {
        listGenres = new JList();
        scrollPaneGenres.setViewportView(listGenres);
      }
    }
    {
      JButton btnAddGenre = new JButton("");
      btnAddGenre.setAction(new AddGenreAction());
      btnAddGenre.setIcon(IconManager.LIST_ADD);
      btnAddGenre.setMargin(new Insets(2, 2, 2, 2));
      details2Panel.add(btnAddGenre, "6, 4, right, top");
    }
    {
      JButton btnRemoveActor = new JButton(BUNDLE.getString("cast.actor.remove")); //$NON-NLS-1$
      btnRemoveActor.setMargin(new Insets(2, 2, 2, 2));
      btnRemoveActor.setAction(new RemoveActorAction());
      btnRemoveActor.setIcon(IconManager.LIST_REMOVE);
      details2Panel.add(btnRemoveActor, "2,6, right, top");
    }

    {
      JButton btnRemoveGenre = new JButton("");
      btnRemoveGenre.setAction(new RemoveGenreAction());
      btnRemoveGenre.setMargin(new Insets(2, 2, 2, 2));
      btnRemoveGenre.setIcon(IconManager.LIST_REMOVE);
      details2Panel.add(btnRemoveGenre, "6, 6, right, top");
    }
    {
      cbGenres = new AutocompleteComboBox(MediaGenres.values());
      cbGenres.setEditable(true);
      details2Panel.add(cbGenres, "8,8");
    }

    // {
    // JLabel lblTrailer = new JLabel(BUNDLE.getString("metatag.trailer")); //$NON-NLS-1$
    // details2Panel.add(lblTrailer, "2, 10, right, default");
    // }
    // {
    // JScrollPane scrollPaneTrailer = new JScrollPane();
    // details2Panel.add(scrollPaneTrailer, "4, 10, 5, 5");
    // tableTrailer = new JTable();
    // scrollPaneTrailer.setViewportView(tableTrailer);
    // }
    // {
    // JButton btnAddTrailer = new JButton("");
    // btnAddTrailer.setAction(new AddTrailerAction());
    // btnAddTrailer.setIcon(IconManager.LIST_ADD);
    // btnAddTrailer.setMargin(new Insets(2, 2, 2, 2));
    // details2Panel.add(btnAddTrailer, "2, 12, right, top");
    // }
    // {
    // JButton btnRemoveTrailer = new JButton("");
    // btnRemoveTrailer.setAction(new RemoveTrailerAction());
    // btnRemoveTrailer.setIcon(IconManager.LIST_REMOVE);
    // btnRemoveTrailer.setMargin(new Insets(2, 2, 2, 2));
    // details2Panel.add(btnRemoveTrailer, "2, 14, right, top");
    // }
    {
      JLabel lblTags = new JLabel(BUNDLE.getString("metatag.tags")); //$NON-NLS-1$
      details2Panel.add(lblTags, "2, 10, right, default");
    }
    {
      JScrollPane scrollPaneTags = new JScrollPane();
      details2Panel.add(scrollPaneTags, "4, 10, 1, 5");
      listTags = new JList();
      scrollPaneTags.setViewportView(listTags);
    }
    {
      JButton btnAddTag = new JButton("");
      btnAddTag.setAction(new AddTagAction());
      btnAddTag.setIcon(IconManager.LIST_ADD);
      btnAddTag.setMargin(new Insets(2, 2, 2, 2));
      details2Panel.add(btnAddTag, "2, 12, right, top");
    }
    {
      JButton btnRemoveTag = new JButton("");
      btnRemoveTag.setAction(new RemoveTagAction());
      btnRemoveTag.setIcon(IconManager.LIST_REMOVE);
      btnRemoveTag.setMargin(new Insets(2, 2, 2, 2));
      details2Panel.add(btnRemoveTag, "2, 14, right, top");
    }
    {
      cbTags = new AutocompleteComboBox(tvShowList.getTagsInTvShows().toArray());
      cbTags.setEditable(true);
      details2Panel.add(cbTags, "4, 16");
    }

    /**
     * extra artwork pane
     */
    {
      JPanel artworkPanel = new JPanel();
      tabbedPane.addTab(BUNDLE.getString("metatag.extraartwork"), null, artworkPanel, null); //$NON-NLS-1$
      artworkPanel.setLayout(new FormLayout(
          new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("250px:grow"), FormFactory.RELATED_GAP_COLSPEC,
              ColumnSpec.decode("250px:grow"), FormFactory.RELATED_GAP_COLSPEC, },
          new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
              RowSpec.decode("50px:grow(2)"), FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
              RowSpec.decode("200px:grow(2)"), FormFactory.RELATED_GAP_ROWSPEC, RowSpec.decode("default:grow"), }));
      {
        JLabel lblLogoT = new JLabel("Logo");
        artworkPanel.add(lblLogoT, "2, 2");
      }
      {
        lblLogo = new ImageLabel();
        lblLogo.setAlternativeText(BUNDLE.getString("image.notfound.logo")); //$NON-NLS-1$
        lblLogo.addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.LOGO, tvShowList.getArtworkProviders(), lblLogo, null,
                null, MediaType.TV_SHOW);
            dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
            dialog.setVisible(true);
          }
        });
        lblLogo.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        artworkPanel.add(lblLogo, "2, 4, 3, 1, fill, fill");
      }
      {
        JLabel lblClearartT = new JLabel("ClearArt");
        artworkPanel.add(lblClearartT, "2, 6");
      }
      {
        JLabel lblThumbT = new JLabel("Thumb");
        artworkPanel.add(lblThumbT, "4, 6");
      }
      {
        lblClearart = new ImageLabel();
        lblClearart.setAlternativeText(BUNDLE.getString("image.notfound.clearart")); //$NON-NLS-1$
        lblClearart.addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.CLEARART, tvShowList.getArtworkProviders(),
                lblClearart, null, null, MediaType.TV_SHOW);
            dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
            dialog.setVisible(true);
          }
        });
        lblClearart.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        artworkPanel.add(lblClearart, "2, 8, fill, fill");
      }
      {
        lblThumb = new ImageLabel();
        lblThumb.setAlternativeText(BUNDLE.getString("image.notfound.thumb")); //$NON-NLS-1$
        lblThumb.addMouseListener(new MouseAdapter() {
          @Override
          public void mouseClicked(MouseEvent e) {
            ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.THUMB, tvShowList.getArtworkProviders(), lblThumb,
                null, null, MediaType.TV_SHOW);
            dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
            dialog.setVisible(true);
          }
        });
        lblThumb.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        artworkPanel.add(lblThumb, "4, 8, fill, fill");
      }

    }
    tabbedPane.addTab(BUNDLE.getString("metatag.episodes"), episodesPanel); //$NON-NLS-1$
    episodesPanel.setLayout(new FormLayout(
        new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC,
            ColumnSpec.decode("default:grow"), FormFactory.RELATED_GAP_COLSPEC, },
        new RowSpec[] { FormFactory.RELATED_GAP_ROWSPEC, FormFactory.DEFAULT_ROWSPEC, FormFactory.RELATED_GAP_ROWSPEC,
            RowSpec.decode("default:grow"), }));
    {
      JButton btnCloneEpisode = new JButton("");
      btnCloneEpisode.setAction(new CloneEpisodeAction());
      episodesPanel.add(btnCloneEpisode, "2, 2");
    }
    {
      JScrollPane scrollPaneEpisodes = new JScrollPane();
      episodesPanel.add(scrollPaneEpisodes, "4, 2, 1, 3, fill, fill");
      {
        tableEpisodes = new JTable();
        scrollPaneEpisodes.setViewportView(tableEpisodes);
      }
    }
    {
      JButton btnRemoveEpisode = new JButton("");
      btnRemoveEpisode.setAction(new RemoveEpisodeAction());
      btnRemoveEpisode.setIcon(IconManager.LIST_REMOVE);
      episodesPanel.add(btnRemoveEpisode, "2, 4, default, top");
    }

    /**
     * Button pane
     */
    {
      JPanel bottomPane = new JPanel();
      getContentPane().add(bottomPane, BorderLayout.SOUTH);
      bottomPane.setLayout(
          new FormLayout(new ColumnSpec[] { ColumnSpec.decode("371px:grow"), FormFactory.DEFAULT_COLSPEC, FormFactory.RELATED_GAP_COLSPEC, },
              new RowSpec[] { FormFactory.LINE_GAP_ROWSPEC, RowSpec.decode("25px"), FormFactory.RELATED_GAP_ROWSPEC, }));

      JPanel buttonPane = new JPanel();
      bottomPane.add(buttonPane, "2, 2, left, top");
      EqualsLayout layout = new EqualsLayout(5);
      layout.setMinWidth(100);
      buttonPane.setLayout(layout);
      {
        JButton okButton = new JButton(BUNDLE.getString("Button.ok")); //$NON-NLS-1$
        buttonPane.add(okButton);
        okButton.setAction(new OKAction());
        okButton.setActionCommand("OK");
        getRootPane().setDefaultButton(okButton);
      }
      {
        JButton cancelButton = new JButton(BUNDLE.getString("Button.cancel")); //$NON-NLS-1$
        buttonPane.add(cancelButton);
        cancelButton.setAction(new CancelAction());
        cancelButton.setActionCommand("Cancel");
      }
      if (inQueue) {
        JButton btnAbort = new JButton(BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$
        btnAbort.setAction(new AbortAction());
        buttonPane.add(btnAbort);
      }

    }

    initDataBindings();

    {
      lvlTvShowPath.setText(tvShow.getPath());
      tfTitle.setText(tvShow.getTitle());
      tfSorttitle.setText(tvShow.getSortTitle());
      tfImdbId.setText(tvShow.getImdbId());

      tfTvdbId.setText(tvShow.getIdAsString(Constants.TVDBID));
      tpPlot.setText(tvShow.getPlot());
      lblPoster.setImagePath(tvShow.getPoster());
      lblThumb.setImagePath(tvShowToEdit.getArtworkFilename(MediaFileType.THUMB));
      lblLogo.setImagePath(tvShowToEdit.getArtworkFilename(MediaFileType.LOGO));
      lblClearart.setImagePath(tvShowToEdit.getArtworkFilename(MediaFileType.CLEARART));
      spRuntime.setValue(Integer.valueOf(tvShow.getRuntime()));
      cbStatus.setSelectedItem(tvShow.getStatus());
      tfStudio.setText(tvShow.getStudio());

      int year = 0;
      try {
        year = Integer.valueOf(tvShow.getYear());
      }
      catch (Exception e) {
      }
      spYear.setValue(year);

      spYear.setEditor(new JSpinner.NumberEditor(spYear, "#"));
      spRating.setModel(new SpinnerNumberModel(tvShow.getRating(), 0.0, 10.0, 0.1));
      SimpleDateFormat dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM);
      spPremiered.setEditor(new JSpinner.DateEditor(spPremiered, dateFormat.toPattern()));

      if (tvShow.getFirstAired() != null) {
        spPremiered.setValue(tvShow.getFirstAired());
      }
      else {
        spPremiered.setValue(INITIAL_DATE);
      }

      for (TvShowActor origCast : tvShow.getActors()) {
        TvShowActor actor = new TvShowActor();
        actor.setName(origCast.getName());
        actor.setCharacter(origCast.getCharacter());
        actor.setThumb(origCast.getThumb());
        actors.add(actor);
      }

      for (MediaGenres genre : tvShow.getGenres()) {
        genres.add(genre);
      }

      // for (MediaTrailer trailer : tvShow.getTrailers()) {
      // trailers.add(trailer);
      // }

      for (String tag : tvShowToEdit.getTags()) {
        tags.add(tag);
      }

      List<TvShowEpisode> epl = tvShowToEdit.getEpisodes();
      // custom sort per filename (just this time)
      // for unknown EPs (-1/-1) this is extremely useful to sort like on filesystem
      // and for already renamed ones, it makes no difference
      Collections.sort(epl, new Comparator<TvShowEpisode>() {
        public int compare(TvShowEpisode s1, TvShowEpisode s2) {
          return s1.getMediaFiles(MediaFileType.VIDEO).get(0).getFile().compareTo(s2.getMediaFiles(MediaFileType.VIDEO).get(0).getFile());
        }
      });

      for (TvShowEpisode episode : epl) {
        TvShowEpisodeEditorContainer container = new TvShowEpisodeEditorContainer();
        container.tvShowEpisode = episode;
        container.dvdOrder = episode.isDvdOrder();
        container.season = episode.getSeason();
        container.episode = episode.getEpisode();
        episodes.add(container);
      }

      if (((DefaultComboBoxModel) cbCertification.getModel()).getIndexOf(tvShow.getCertification()) == -1) {
        cbCertification.addItem(tvShow.getCertification());
      }
      cbCertification.setSelectedItem(tvShow.getCertification());

    }
    lblBanner = new ImageLabel();
    lblBanner.setAlternativeText(BUNDLE.getString("image.notfound.banner")); //$NON-NLS-1$
    lblBanner.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    lblBanner.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.BANNER, tvShowList.getArtworkProviders(), lblBanner, null,
            null, MediaType.TV_SHOW);
        dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
        dialog.setVisible(true);
      }
    });
    details1Panel.add(lblBanner, "4, 22, 7, 3, fill, fill");
    lblBanner.setImagePath(tvShow.getBanner());
    {
      // JLabel lblFanart = new JLabel("");
      lblFanart = new ImageLabel();
      lblFanart.setAlternativeText(BUNDLE.getString("image.notfound.fanart")); //$NON-NLS-1$
      lblFanart.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
      lblFanart.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
          ImageChooserDialog dialog = new ImageChooserDialog(tvShowToEdit.getIds(), ImageType.FANART, tvShowList.getArtworkProviders(), lblFanart,
              null, null, MediaType.TV_SHOW);
          dialog.setLocationRelativeTo(MainWindow.getActiveInstance());
          dialog.setVisible(true);
        }
      });
      details1Panel.add(lblFanart, "12, 20, 3, 5, fill, fill");
    }
    lblFanart.setImagePath(tvShow.getFanart());

    // adjust columnn titles - we have to do it this way - thx to windowbuilder pro
    tableActors.getColumnModel().getColumn(0).setHeaderValue(BUNDLE.getString("metatag.name")); //$NON-NLS-1$
    tableActors.getColumnModel().getColumn(1).setHeaderValue(BUNDLE.getString("metatag.role")); //$NON-NLS-1$

    // tableTrailer.getColumnModel().getColumn(0).setHeaderValue(BUNDLE.getString("metatag.nfo")); //$NON-NLS-1$
    // tableTrailer.getColumnModel().getColumn(1).setHeaderValue(BUNDLE.getString("metatag.name")); //$NON-NLS-1$
    // tableTrailer.getColumnModel().getColumn(2).setHeaderValue(BUNDLE.getString("metatag.source")); //$NON-NLS-1$
    // tableTrailer.getColumnModel().getColumn(3).setHeaderValue(BUNDLE.getString("metatag.quality")); //$NON-NLS-1$
    // tableTrailer.getColumnModel().getColumn(4).setHeaderValue(BUNDLE.getString("metatag.url")); //$NON-NLS-1$

    tableEpisodes.getColumnModel().getColumn(0).setHeaderValue(BUNDLE.getString("metatag.title")); //$NON-NLS-1$
    tableEpisodes.getColumnModel().getColumn(1).setHeaderValue(BUNDLE.getString("metatag.filename")); //$NON-NLS-1$
    tableEpisodes.getColumnModel().getColumn(2).setHeaderValue(BUNDLE.getString("metatag.season")); //$NON-NLS-1$
    tableEpisodes.getColumnModel().getColumn(3).setHeaderValue(BUNDLE.getString("metatag.episode")); //$NON-NLS-1$
    tableEpisodes.getColumnModel().getColumn(4).setHeaderValue(BUNDLE.getString("metatag.dvdorder")); //$NON-NLS-1$
    tableEpisodes.getColumnModel().getColumn(2).setMaxWidth(150);
    tableEpisodes.getColumnModel().getColumn(3).setMaxWidth(150);
    tableEpisodes.getColumnModel().getColumn(2).setCellEditor(new TableSpinnerEditor());
    tableEpisodes.getColumnModel().getColumn(3).setCellEditor(new TableSpinnerEditor());

    // adjust table columns
    TableColumnResizer.adjustColumnPreferredWidths(tableActors, 6);
    // TableColumnResizer.adjustColumnPreferredWidths(tableTrailer, 6);
    TableColumnResizer.adjustColumnPreferredWidths(tableEpisodes, 6);

    // // implement listener to simulate button group
    // tableTrailer.getModel().addTableModelListener(new TableModelListener() {
    // @Override
    // public void tableChanged(TableModelEvent arg0) {
    // // click on the checkbox
    // if (arg0.getColumn() == 0) {
    // int row = arg0.getFirstRow();
    // MediaTrailer changedTrailer = trailers.get(row);
    // // if flag inNFO was changed, change all other trailers flags
    // if (changedTrailer.getInNfo()) {
    // for (MediaTrailer trailer : trailers) {
    // if (trailer != changedTrailer) {
    // trailer.setInNfo(Boolean.FALSE);
    // }
    // }
    // }
    // }
    // }
    // });
  }

  private class OKAction extends AbstractAction {
    private static final long serialVersionUID = 6699599213348390696L;

    public OKAction() {
      putValue(NAME, BUNDLE.getString("Button.ok")); //$NON-NLS-1$
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tvshow.change")); //$NON-NLS-1$
      putValue(SMALL_ICON, IconManager.APPLY);
      putValue(LARGE_ICON_KEY, IconManager.APPLY);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      tvShowToEdit.setTitle(tfTitle.getText());
      tvShowToEdit.setSortTitle(tfSorttitle.getText());
      tvShowToEdit.setYear(String.valueOf(spYear.getValue()));
      tvShowToEdit.setPlot(tpPlot.getText());
      tvShowToEdit.setRuntime((Integer) spRuntime.getValue());
      tvShowToEdit.setImdbId(tfImdbId.getText());

      if (StringUtils.isNotBlank(tfTvdbId.getText())) {
        try {
          tvShowToEdit.setTvdbId(tfTvdbId.getText());
        }
        catch (NumberFormatException ex) {
          JOptionPane.showMessageDialog(null, BUNDLE.getString("tmdb.wrongformat")); //$NON-NLS-1$
          return;
        }
      }

      Object certification = cbCertification.getSelectedItem();
      if (certification instanceof Certification) {
        tvShowToEdit.setCertification((Certification) certification);
      }

      if (!StringUtils.isEmpty(lblPoster.getImageUrl()) && !lblPoster.getImageUrl().equals(tvShowToEdit.getPosterUrl())) {
        tvShowToEdit.setPosterUrl(lblPoster.getImageUrl());
        tvShowToEdit.downloadArtwork(MediaFileType.POSTER);
      }

      if (!StringUtils.isEmpty(lblFanart.getImageUrl()) && !lblFanart.getImageUrl().equals(tvShowToEdit.getFanartUrl())) {
        tvShowToEdit.setFanartUrl(lblFanart.getImageUrl());
        tvShowToEdit.downloadArtwork(MediaFileType.FANART);
      }

      if (!StringUtils.isEmpty(lblBanner.getImageUrl()) && !lblBanner.getImageUrl().equals(tvShowToEdit.getBannerUrl())) {
        tvShowToEdit.setBannerUrl(lblBanner.getImageUrl());
        tvShowToEdit.downloadArtwork(MediaFileType.BANNER);
      }

      if (!StringUtils.isEmpty(lblLogo.getImageUrl()) && !lblLogo.getImageUrl().equals(tvShowToEdit.getArtworkUrl(MediaFileType.LOGO))) {
        tvShowToEdit.setArtworkUrl(lblLogo.getImageUrl(), MediaFileType.LOGO);
        tvShowToEdit.downloadArtwork(MediaFileType.LOGO);
      }

      if (!StringUtils.isEmpty(lblClearart.getImageUrl()) && !lblClearart.getImageUrl().equals(tvShowToEdit.getArtworkUrl(MediaFileType.CLEARART))) {
        tvShowToEdit.setArtworkUrl(lblClearart.getImageUrl(), MediaFileType.CLEARART);
        tvShowToEdit.downloadArtwork(MediaFileType.CLEARART);
      }

      if (!StringUtils.isEmpty(lblThumb.getImageUrl()) && !lblThumb.getImageUrl().equals(tvShowToEdit.getArtworkUrl(MediaFileType.THUMB))) {
        tvShowToEdit.setArtworkUrl(lblThumb.getImageUrl(), MediaFileType.THUMB);
        tvShowToEdit.downloadArtwork(MediaFileType.THUMB);
      }

      tvShowToEdit.setProductionCompany(tfStudio.getText());
      tvShowToEdit.setActors(actors);
      tvShowToEdit.setGenres(genres);

      // tvShowToEdit.removeAllTrailers();
      // for (MediaTrailer trailer : trailers) {
      // tvShowToEdit.addTrailer(trailer);
      // }

      tvShowToEdit.setTags(tags);
      tvShowToEdit.setDateAdded((Date) spDateAdded.getValue());

      Date premieredDate = (Date) spPremiered.getValue();
      if (!premieredDate.equals(INITIAL_DATE)) {
        tvShowToEdit.setFirstAired(premieredDate);
      }

      tvShowToEdit.setStatus(cbStatus.getSelectedItem().toString());

      double tempRating = (Double) spRating.getValue();
      float rating = (float) tempRating;
      if (tvShowToEdit.getRating() != rating) {
        tvShowToEdit.setRating(rating);
        tvShowToEdit.setVotes(1);
      }

      // adapt episodes according to the episode table (in a 2 way sync)
      // remove episodes
      for (int i = tvShowToEdit.getEpisodeCount() - 1; i >= 0; i--) {
        boolean found = false;
        TvShowEpisode episode = tvShowToEdit.getEpisodes().get(i);
        for (TvShowEpisodeEditorContainer container : episodes) {
          if (container.tvShowEpisode == episode) {
            found = true;
            break;
          }
        }

        if (!found) {
          tvShowToEdit.removeEpisode(episode);
        }
      }

      // add episodes
      for (TvShowEpisodeEditorContainer container : episodes) {
        boolean found = false;
        boolean shouldStore = false;

        if (container.dvdOrder != container.tvShowEpisode.isDvdOrder()) {
          container.tvShowEpisode.setDvdOrder(container.dvdOrder);
          shouldStore = true;
        }

        if (container.episode != container.tvShowEpisode.getEpisode()) {
          if (container.dvdOrder) {
            container.tvShowEpisode.setDvdEpisode(container.episode);
          }
          else {
            container.tvShowEpisode.setAiredEpisode(container.episode);
          }

          shouldStore = true;
        }

        if (container.season != container.tvShowEpisode.getSeason()) {
          if (container.dvdOrder) {
            container.tvShowEpisode.setDvdSeason(container.season);
          }
          else {
            container.tvShowEpisode.setAiredSeason(container.season);
          }
          shouldStore = true;
        }

        for (TvShowEpisode episode : tvShowToEdit.getEpisodes()) {
          if (container.tvShowEpisode == episode) {
            found = true;
            break;
          }
        }

        if (!found) {
          container.tvShowEpisode.saveToDb();
          container.tvShowEpisode.writeNFO();
          tvShowToEdit.addEpisode(container.tvShowEpisode);
        }
        else if (shouldStore) {
          container.tvShowEpisode.saveToDb();
          container.tvShowEpisode.writeNFO();
        }
      }

      tvShowToEdit.saveToDb();
      tvShowToEdit.writeNFO();

      if (Globals.settings.getTvShowSettings().getSyncTrakt()) {
        TmmTask task = new SyncTraktTvTask(null, Arrays.asList(tvShowToEdit));
        TmmTaskManager.getInstance().addUnnamedTask(task);
      }

      setVisible(false);
    }
  }

  private class CancelAction extends AbstractAction {
    private static final long serialVersionUID = -4617793684152607277L;

    public CancelAction() {
      putValue(NAME, BUNDLE.getString("Button.cancel")); //$NON-NLS-1$
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("edit.discard")); //$NON-NLS-1$
      putValue(SMALL_ICON, IconManager.CANCEL);
      putValue(LARGE_ICON_KEY, IconManager.CANCEL);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      setVisible(false);
    }
  }

  private class AddActorAction extends AbstractAction {
    private static final long serialVersionUID = -5879601617842300526L;

    public AddActorAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("cast.actor.add")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      TvShowActor actor = new TvShowActor(BUNDLE.getString("cast.actor.unknown"), BUNDLE.getString("cast.role.unknown")); //$NON-NLS-1$
      actors.add(0, actor);
    }
  }

  private class RemoveActorAction extends AbstractAction {
    private static final long serialVersionUID = 6970920169867315771L;

    public RemoveActorAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("cast.actor.remove")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      int row = tableActors.getSelectedRow();
      if (row > -1) {
        row = tableActors.convertRowIndexToModel(row);
        actors.remove(row);
      }
    }
  }

  private class AddGenreAction extends AbstractAction {
    private static final long serialVersionUID = 6666302391216952247L;

    public AddGenreAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("genre.add")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      MediaGenres newGenre = null;
      Object item = cbGenres.getSelectedItem();

      // genre
      if (item instanceof MediaGenres) {
        newGenre = (MediaGenres) item;
      }

      // newly created genre?
      if (item instanceof String) {
        newGenre = MediaGenres.getGenre((String) item);
      }

      // add genre if it is not already in the list
      if (newGenre != null && !genres.contains(newGenre)) {
        genres.add(newGenre);
      }
    }
  }

  private class RemoveGenreAction extends AbstractAction {
    private static final long serialVersionUID = -5459615776560234688L;

    public RemoveGenreAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("genre.remove")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      MediaGenres newGenre = (MediaGenres) listGenres.getSelectedValue();
      // remove genre
      if (newGenre != null) {
        genres.remove(newGenre);
      }
    }
  }

  /*
   * private class AddTrailerAction extends AbstractAction { private static final long serialVersionUID = 5448745104881472479L;
   *
   * public AddTrailerAction() { putValue(SHORT_DESCRIPTION, BUNDLE.getString("trailer.add")); //$NON-NLS-1$ }
   *
   * @Override public void actionPerformed(ActionEvent e) { MediaTrailer trailer = new MediaTrailer(); trailer.setName("unknown");
   * trailer.setProvider("unknown"); trailer.setQuality("unknown"); trailer.setUrl("http://"); trailers.add(0, trailer); } }
   *
   * private class RemoveTrailerAction extends AbstractAction { private static final long serialVersionUID = -6956921050689930101L;
   *
   * public RemoveTrailerAction() { putValue(SHORT_DESCRIPTION, BUNDLE.getString("trailer.remove")); //$NON-NLS-1$ }
   *
   * @Override public void actionPerformed(ActionEvent e) { int row = tableTrailer.getSelectedRow(); if (row > -1) { row =
   * tableTrailer.convertRowIndexToModel(row); trailers.remove(row); } } }
   */

  /**
   * Shows the dialog and returns whether the work on the queue should be continued.
   *
   * @return true, if successful
   */
  public boolean showDialog() {
    setVisible(true);
    return continueQueue;
  }

  private class AddTagAction extends AbstractAction {
    private static final long serialVersionUID = 9160043031922897785L;

    public AddTagAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tag.add")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      String newTag = (String) cbTags.getSelectedItem();
      if (StringUtils.isBlank(newTag)) {
        return;
      }

      boolean tagFound = false;

      // search if this tag already has been added
      for (String tag : tags) {
        if (tag.equals(newTag)) {
          tagFound = true;
          break;
        }
      }

      // add tag
      if (!tagFound) {
        tags.add(newTag);
      }
    }
  }

  private class RemoveTagAction extends AbstractAction {
    private static final long serialVersionUID = -1580945350962234235L;

    public RemoveTagAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tag.remove")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      String tag = (String) listTags.getSelectedValue();
      tags.remove(tag);
    }
  }

  private class AbortAction extends AbstractAction {
    private static final long serialVersionUID = -7652218354710642510L;

    public AbortAction() {
      putValue(NAME, BUNDLE.getString("Button.abortqueue")); //$NON-NLS-1$
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tvshow.edit.abortqueue.desc")); //$NON-NLS-1$
      putValue(SMALL_ICON, IconManager.PROCESS_STOP);
      putValue(LARGE_ICON_KEY, IconManager.PROCESS_STOP);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      continueQueue = false;
      setVisible(false);
    }
  }

  public class TvShowEpisodeEditorContainer {
    TvShowEpisode tvShowEpisode;
    int           season;
    int           episode;
    boolean       dvdOrder = false;

    public String getEpisodeTitle() {
      return tvShowEpisode.getTitle();
    }

    public String getMediaFilename() {
      List<MediaFile> mfs = tvShowEpisode.getMediaFiles(MediaFileType.VIDEO);
      if (mfs != null && mfs.size() > 0) {
        return mfs.get(0).getFile().getAbsolutePath();
      }
      else {
        return "";
      }
    }

    public int getEpisode() {
      return episode;
    }

    public void setEpisode(int episode) {
      this.episode = episode;
    }

    public int getSeason() {
      return season;
    }

    public void setSeason(int season) {
      this.season = season;
    }

    public boolean isDvdOrder() {
      return this.dvdOrder;
    }

    public void setDvdOrder(boolean dvdOrder) {
      this.dvdOrder = dvdOrder;
    }
  }

  protected void initDataBindings() {
    jTableBinding = SwingBindings.createJTableBinding(UpdateStrategy.READ, actors, tableActors);
    //
    BeanProperty<TvShowActor, String> castBeanProperty = BeanProperty.create("name");
    jTableBinding.addColumnBinding(castBeanProperty);
    //
    BeanProperty<TvShowActor, String> castBeanProperty_1 = BeanProperty.create("character");
    jTableBinding.addColumnBinding(castBeanProperty_1);
    //
    jTableBinding.bind();
    //
    jListBinding = SwingBindings.createJListBinding(UpdateStrategy.READ, genres, listGenres);
    jListBinding.bind();
    //
    // jTableBinding_1 = SwingBindings.createJTableBinding(UpdateStrategy.READ, trailers, tableTrailer);
    //
    // BeanProperty<MediaTrailer, Boolean> trailerBeanProperty = BeanProperty.create("inNfo");
    // jTableBinding_1.addColumnBinding(trailerBeanProperty).setColumnClass(Boolean.class);
    //
    // BeanProperty<MediaTrailer, String> trailerBeanProperty_1 = BeanProperty.create("name");
    // jTableBinding_1.addColumnBinding(trailerBeanProperty_1);
    //
    // BeanProperty<MediaTrailer, String> trailerBeanProperty_2 = BeanProperty.create("provider");
    // jTableBinding_1.addColumnBinding(trailerBeanProperty_2);
    //
    // BeanProperty<MediaTrailer, String> trailerBeanProperty_3 = BeanProperty.create("quality");
    // jTableBinding_1.addColumnBinding(trailerBeanProperty_3);
    //
    // BeanProperty<MediaTrailer, String> trailerBeanProperty_4 = BeanProperty.create("url");
    // jTableBinding_1.addColumnBinding(trailerBeanProperty_4);
    //
    // jTableBinding_1.bind();
    //
    BeanProperty<TvShowList, List<String>> tvShowListBeanProperty = BeanProperty.create("tagsInTvShows");
    jComboBinding = SwingBindings.createJComboBoxBinding(UpdateStrategy.READ, tvShowList, tvShowListBeanProperty, cbTags);
    jComboBinding.bind();
    //
    jListBinding_1 = SwingBindings.createJListBinding(UpdateStrategy.READ, tags, listTags);
    jListBinding_1.bind();
    //
    jTableBinding_2 = SwingBindings.createJTableBinding(UpdateStrategy.READ, episodes, tableEpisodes);
    //
    BeanProperty<TvShowEpisodeEditorContainer, String> tvShowEpisodeEditorContainerBeanProperty = BeanProperty.create("episodeTitle");
    jTableBinding_2.addColumnBinding(tvShowEpisodeEditorContainerBeanProperty);
    //
    BeanProperty<TvShowEpisodeEditorContainer, String> tvShowEpisodeEditorContainerBeanProperty_1 = BeanProperty.create("mediaFilename");
    jTableBinding_2.addColumnBinding(tvShowEpisodeEditorContainerBeanProperty_1);
    //
    BeanProperty<TvShowEpisodeEditorContainer, Integer> tvShowEpisodeEditorContainerBeanProperty_2 = BeanProperty.create("season");
    jTableBinding_2.addColumnBinding(tvShowEpisodeEditorContainerBeanProperty_2);
    //
    BeanProperty<TvShowEpisodeEditorContainer, Integer> tvShowEpisodeEditorContainerBeanProperty_3 = BeanProperty.create("episode");
    jTableBinding_2.addColumnBinding(tvShowEpisodeEditorContainerBeanProperty_3);
    //
    BeanProperty<TvShowEpisodeEditorContainer, Boolean> tvShowEpisodeEditorContainerBeanProperty_4 = BeanProperty.create("dvdOrder");
    jTableBinding_2.addColumnBinding(tvShowEpisodeEditorContainerBeanProperty_4).setColumnClass(Boolean.class);
    //
    jTableBinding_2.bind();
  }

  @Override
  public void dispose() {
    super.dispose();
    jTableBinding.unbind();
    jListBinding.unbind();
    // jTableBinding_1.unbind();
    jComboBinding.unbind();
    jListBinding_1.unbind();
    jTableBinding_2.unbind();
  }

  @Override
  public void pack() {
    // do not let it pack - it looks weird
  }

  private class CloneEpisodeAction extends AbstractAction {
    private static final long serialVersionUID = -3255090541823134232L;

    public CloneEpisodeAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tvshowepisode.clone")); //$NON-NLS-1$
      putValue(SMALL_ICON, IconManager.COPY);
      putValue(LARGE_ICON_KEY, IconManager.COPY);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
      int row = tableEpisodes.getSelectedRow();
      if (row > -1) {
        row = tableEpisodes.convertRowIndexToModel(row);
        TvShowEpisodeEditorContainer origContainer = episodes.get(row);
        TvShowEpisodeEditorContainer newContainer = new TvShowEpisodeEditorContainer();
        newContainer.tvShowEpisode = new TvShowEpisode(origContainer.tvShowEpisode);
        newContainer.tvShowEpisode.setTitle(origContainer.tvShowEpisode.getTitle() + " (clone)");
        newContainer.episode = -1;
        newContainer.season = newContainer.tvShowEpisode.getSeason();
        episodes.add(row + 1, newContainer);
      }
    }
  }

  private class RemoveEpisodeAction extends AbstractAction {
    private static final long serialVersionUID = -8233854057648972649L;

    public RemoveEpisodeAction() {
      putValue(SHORT_DESCRIPTION, BUNDLE.getString("tvshowepisode.remove")); //$NON-NLS-1$
    }

    @Override
    public void actionPerformed(ActionEvent e) {
      int row = tableEpisodes.getSelectedRow();
      if (row > -1) {
        row = tableEpisodes.convertRowIndexToModel(row);
        episodes.remove(row);
      }
    }
  }
}


text:
#pragma once

#include "Volt/Core/Core.h"
#include "Volt/Graphics/Input.h"
#include "Volt/Graphics/Viewport.h"

namespace Volt {

class Game;

/**
 *  Manages the graphics window.
 */
class SDLWindow : public Viewport {
public:
    SDLWindow (Game* game, const string& name,
            int w, int h, bool fullscreen);
    ~SDLWindow ();

    virtual int width () const;
    virtual int height () const;

    virtual void SwapBuffers ();

    void Close ();

    void Screenshot (const string& filename);

    bool IsKeyPressed (SDLKey key);
    void UpdateInput ();

    void SetTitle (string title);

private:
    Game* m_game;
    void* m_screen;
};

#define G_Window dynamic_cast<Volt::SDLWindow*>(Volt::Viewport::Instance())
}