def embed_or_extract_with_method(embed, method, filename, destfilename, message, msglen):
    if embed:
        print "embedding with method " + `method+1` + ", algo: " + method_to_algo[method]
    else:
        p_message = libstego.new_charp()
        p_msglen = libstego.new_intp()
        print "extracting with method " + `method+1` + ", algo: " + method_to_algo[method]

    if method_to_algo[method] == "PQ":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return

        para = methods[method]
        if embed:
            err = libstego.pq_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpeg_int, stego_data)
                if err != 0:
                    print "Error while integrating JPEG"
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
                if err != 0:
                    print "Error while writing JPEG"
            else:
                print "An error occured while embedding with PQ."
        else:
            err = libstego.pq_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "An error occured while extracting with PQ."

        # cleanup
        libstegofile.io_jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "F5":
        # prepare data strucures
        jpeg_data = libstegofile.jpeg_data_t()
        stego_data = libstegofile.jpeg_data_t()
        jpeg_int = libstegofile.jpeg_internal_data_t()

        # read file data
        err = libstegofile.io_jpeg_read(filename, jpeg_data, jpeg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading JPG"
            return


        para = methods[method]
        if embed:
            err = libstego.f5_embed(jpeg_data, stego_data, message, len(message) + 1, para)
            if err == 0:
                err = libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                err = libstegofile.io_jpeg_write(destfilename, jpeg_int)
            else:
                print "Error while embedding with F5."
        else:
            err = libstego.f5_extract(jpeg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with F5."

        # cleanup
        libstegofile.jpeg_cleanup_data(jpeg_data)
        libstegofile.io_jpeg_cleanup_data(stego_data)
        libstegofile.io_jpeg_cleanup_internal_data(jpeg_int)


    elif method_to_algo[method] == "Adv. Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.method = 1
            err = libstego.gifshuffle_embed(pwmsg_data, stego_data,
                    message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            pw_message = para.password
            pw_message_len = para.pwlen
            para.password = ""
            para.pwlen = 0
            pwmsg_data = libstegofile.palette_data_t()
            para.method = 0
            err = libstego.gifshuffle_embed(palette_data, pwmsg_data, pw_message,
                    pw_message_len, para)
            para.adv_pal = pwmsg_data
            para.method = 1
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Gifshuffle":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.gifshuffle_embed(palette_data, stego_data, message, msglen, para)
            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.gifshuffle_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Frirui":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            err = libstego.frirui_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            err = libstego.frirui_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)


    elif method_to_algo[method] == "Sort/Unsort":
        # prepare data strucures
        palette_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()

        # read file data
        err = libstegofile.io_gif_read(filename, palette_data, gif_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading GIF"
            return

        para = methods[method]
        if embed:
            libstego.sortunsort_embed(palette_data, stego_data, message, msglen, para)

            err = libstegofile.io_gif_integrate(gif_int, stego_data)
            err = libstegofile.io_gif_write(destfilename, gif_int)
        else:
            libstego.sortunsort_extract(palette_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(palette_data)
        libstegofile.io_gif_cleanup_internal(gif_int)

    elif method_to_algo[method] == "CPT":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            print(para.password)
            print(para.pwlen)
            print(para.block_width)
            print(para.block_height)
            err = libstego.cpt_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.cpt_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)

    elif method_to_algo[method] == "Battlesteg":
        # prepare data strucures
        rgb_data = libstegofile.rgb_data_t()
        stego_data = libstegofile.rgb_data_t()
        png_int = libstegofile.png_internal_data_t()

        # read file data
        err = libstegofile.io_png_read(filename, rgb_data, png_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading PNG"
            return

        para = methods[method]
        if embed:
            err = libstego.battlesteg_embed(rgb_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_png_integrate(png_int, stego_data)
                err = libstegofile.io_png_write(destfilename, png_int)
        else:
            err = libstego.battlesteg_extract(rgb_data, p_message, p_msglen, para)

        # cleanup
        libstegofile.io_png_cleanup_data(rgb_data)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_internal(png_int)


    elif method_to_algo[method] == "SVG Steg":
        # prepare data strucures
        svg_data = libstegofile.svg_data_t()
        svg_stego = libstegofile.svg_data_t()
        svg_int = libstegofile.svg_internal_data_t()

        # read file data
        err = libstegofile.io_svg_read(filename, svg_data, svg_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading SVG"
            return

        para = methods[method]
        if embed:
            err = libstego.svg_embed(svg_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_svg_integrate(svg_int, stego_data)
                if err != 0:
                    print "Error while integrating SVG"
                err = libstegofile.io_svg_write(destfilename, svg_int)
                if err != 0:
                    print "Error while writing SVG"
            else:
                print "Error while embedding with SVG Stego"
        else:
            err = libstego.svg_extract(svg_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with SVG Stego"

        # cleanup
        libstegofile.svg_cleanup_data(svg_data)
        libstegofile.svg_cleanup_data(stego_data)
        libstegofile.svg_cleanup_internal(svg_int)

    elif method_to_algo[method] == "Echo Hiding":
        # prepare data strucures
        wav_data = libstegofile.wav_data_t()
        stego_data = libstegofile.wav_data_t()
        wav_int = libstegofile.wav_internal_data_t()

        # read file data
        err = libstegofile.io_wav_read(filename, wav_data, wav_int)
        if err != 0:
            # TODO better error handling
            print "Error while reading WAV"
            return

        para = methods[method]
        if embed:
            err = libstego.eh_embed(wav_data, stego_data, message, msglen, para)
            if err == 0:
                err = libstegofile.io_wav_integrate(wav_int, stego_data)
                if err != 0:
                    print "Error while integrating WAV"
                err = libstegofile.io_wav_write(destfilename, wav_int)
                if err != 0:
                    print "Error while writing WAV"
            else:
                print "Error while embedding with Echo Hiding"
        else:
            err = libstego.eh_extract(wav_data, p_message, p_msglen, para)
            if err != 0:
                print "Error while extracting with Echo Hiding"

        # cleanup
        libstegofile.wav_cleanup_data(wav_data)
        libstegofile.wav_cleanup_data(stego_data)
        libstegofile.wav_cleanup_internal(wav_int)


    elif method_to_algo[method] == "Phase Coding":
        # TODO implement
        pass


    elif method_to_algo[method] == "LSB":
        # TODO implement
        pass

    if embed:
        return None
    else:
        message = str(libstego.charp_value(p_message))
        print message
        msglen = libstego.intp_value(p_msglen)
        return message
def embed_or_extract(algo, para, filename, destfilename):
#TODO: File read + Cleanup + implement for earch algo + parameter sets!
#TODO: Return (None) or Return Error
#TODO: After embed call function recursively to call extract (verify msg)
#TODO: Lots of "returns"

    if filename.endswith("jpeg") or filename.endswith("jpg"):
        src_data = libstegofile.jpeg_data_t()
        jpg_int = libstegofile.jpeg_internal_data_t()
        libstegofile.io_jpeg_read(filename, src_data, jpg_int)
        if algo == "PQ":
            if embed:
                stego_data = libstegofile.jpeg_data_t()
                err = libstego.pq_embed(src_data, stego_data, message, len(message) + 1, para)
                if err == 0:
                    libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                    libstegofile.io_jpeg_write(destfilename, jpg_int)
                libstegofile.io_jpeg_cleanup_data(stego_data)
            else:
                err = libstego.pq_extract(src_data, message, msglen, para)
        elif algo == "F5":
            if embed:
                stego_data = libstegofile.jpeg_data_t()
                err = libstego.f5_embed(src_data, stego_data, message, len(message) + 1, para)
                if err == 0:
                    libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                    libstegofile.io_jpeg_write(destfilename, jpg_int)
                libstegofile.io_jpeg_cleanup_data(stego_data)
            else:
                err = libstego.f5_extract(src_data, message, msglen, para)
        """elif algo == "LSB":
            if embed:
                stego_data = libstegofile.jpeg_data_t()
                err = libstego.lsb_embed(src_data, stego_data, message, len(message) + 1, para)
                if err == 0:
                    libstegofile.io_jpeg_integrate(jpg_int, stego_data)
                    libstegofile.io_jpeg_write(destfilename, jpg_int)
                libstegofile.io_jpeg_cleanup_data(stego_data)
            else:
                err = libstego.lsb_extract(src_data, message, msglen, para)"""

        libstegofile.io_jpeg_cleanup_data(src_data)
        libstegofile.io_jpeg_cleanup_internal(jpg_int)
        return err
    elif filename.endswith("gif"):
        src_data = libstegofile.palette_data_t()
        stego_data = libstegofile.palette_data_t()
        gif_int = libstegofile.gif_internal_data_t()
        libstegofile.io_gif_read(filename, src_data, gif_int)
        if algo == "Adv. Gifshuffle":
            if embed:
                pw_message = para.password
                pw_message_len = para.pwlen
                para.password = ""
                para.pwlen = 0
                pwmsg_data = libstegofile.palette_data_t()
                para.method = 0
                libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message,
                        pw_message_len, para)
                para.method = 1
                libstego.gifshuffle_embed(pwmsg_data, stego_data,
                        message, msglen, para)

            else:
                pw_message = para.password
                pw_message_len = para.pwlen
                para.password = ""
                para.pwlen = 0
                pwmsg_data = libstegofile.palette_data_t()
                para.method = 0
                libstego.gifshuffle_embed(src_data, pwmsg_data, pw_message,
                        pw_message_len, para)
                para.adv_pal = pwmsg_data
                para.method = 1
                libstego.gifshuffle_extract(src_data, message,
                        msglen, para)

        elif algo == "Gifshuffle":
            if embed:
                libstego.gifshuffle_embed(src_data, stego_data, message,
                            msglen, para)
            else:
                libstego.gifshuffle_extract(src_data, message,
                            msglen, para)


        elif algo == "Sort/Unsort":
            if embed:
                libstego.sortunsort_embed(src_data, stego_data, message,
                        msglen, para)

            else:
                libstego.sortunsort_extract(src_data, message,
                        msglen, para)


        elif algo == "Frirui":
            if embed:
                libstego.frirui_embed(src_data, stego_data, message,
                        msglen, para)

            else:
                libstego.frirui_extract(src_data, message,
                        msglen, para)


        elif algo == "LSB":
            if embed:
                #embed
                pass
            else:
                #extract
                pass

        # Write back and clean up
        libstegofile.io_gif_integrate(gif_int, stego_data)
        libstegofile.io_gif_write(destfilename, gif_int)
        libstegofile.io_gif_cleanup_data(stego_data)
        libstegofile.io_gif_cleanup_data(src_data)
        libstegofile.io_gif_cleanup_internal(gif_int)

    elif filename.endswith("png"):
        src_data, stego_data, png_int = call_file_read(libstegofile.rgb_data_t,
                                                       libstegofile.png_internal_data_t,
                                                       libstegofile.io_png_read)
        if algo == "CPT":
            call_embed_extract(embed, libstego.cpt_embed, libstego.cpt_extract,
                               src_data, stego_data, message, msglen, para)
        elif algo == "Battlesteg":
            call_embed_extract(embed, libstego.battlesteg_embed, libstego.battlesteg_extract,
                               src_data, stego_data, message, msglen, para)

        elif algo == "LSB":
            call_embed_extract(embed, libstego.lsb_embed, libstego.lsb_extract,
                               src_data, stego_data, message, msglen, para)

        libstegofile.io_png_integrate(png_int, stego_data)
        libstegofile.io_png_write(destfilename, png_int)
        libstegofile.io_png_cleanup_data(stego_data)
        libstegofile.io_png_cleanup_data(src_data)
        libstegofile.io_png_cleanup_internal(png_int)


    elif filename.endswith("wav"):
        if algo == "Echo Hiding":
            if embed:
                #embed
                pass
            else:
                #extract
                pass

        elif algo == "Phase Coding":
            if embed:
                #embed
                pass
            else:
                #extract
                pass

        elif algo == "LSB":
            if embed:
                #embed
                pass
            else:
                #extract
                pass

    elif filename.endswith("svg"):
        if algo == "SVG Steg":
            if embed:
                #embed
                pass
            else:
                #extract
                pass

        elif algo == "LSB":
            if embed:
                #embed
                pass
            else:
                #extract
                pass